1. °í±Þ Äõ¸® ±â¹ý
1.1. iBATIS¿¡¼ XML »ç¿ëÇϱâ
iBATIS ÇÁ·¹ÀÓ¿öÅ©¿¡¼´Â Äõ¸®¿¡ ÆĶó¹ÌÅ͸¦ Àü´ÞÇÒ ¶§³ª ȤÀº Äõ¸® °á°ú¸¦ ¹Ýȯ¹ÞÀ» ¶§XMLÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. µÎ °æ¿ì ¸ðµÎ ²À XMLÀ» »ç¿ëÇÒ ÇÊ¿äµµ ¾øÀ¸¸é¼ XMLÀ» »ç¿ëÇϴ°ÍÀº ±×´ÙÁö ±ÇÀåÇÒ °ÍÀº ¸øµÈ´Ù. ´ë½Å POJO¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ´ëºÎºÐÀÇ °æ¿ì¿¡ ÈξÀ ´õÈ¿À²ÀûÀ̱⠶§¹®ÀÌ´Ù.
6.1.1 XML ÆĶó¹ÌÅÍ
¿ÏÀüÈ÷ µ¿ÀÏÇÑ ±¸Á¶¸¦ °®Ãß°í ÀÖ´Â ¹®ÀÚ¿À̳ª DOM °´Ã¼¸¦ ÅëÇؼ XMLÀ» ¸ÅÇÎ ±¸¹®¿¡ÆĶó¹ÌÅÍ·Î ³Ñ°ÜÁÙ ¼ö ÀÖ´Ù.
±¸Á¶ÀÇ ÇüÅ´ ÆĶó¹ÌÅÍ·Î Àü´ÞÇÒ °ªÀÌ ÆĶó¹ÌÅÍÀÇ À̸§À» ÀǹÌÇÏ´Â ¿ä¼Ò·Î °¨½ÎÁ® ÀÖ°í ±× ¿ä¼Ò¸¦ ´Ù½Ã parameter ¿ä¼Ò·Î °¨½Î°í ÀÖ´Â °ÍÀÌ´Ù. ¿¹¸¦ º¸ÀÚ.
ÀÌ ¿¹¿¡¼ ¸ÅÇÎ ±¸¹®Àº °ªÀÌ 3ÀÌ°í À̸§ÀÌ ¡°accountId¡±ÀÎ ÆĶó¹ÌÅÍ ÇÑ °³¸¦ Àü´Þ¹Þ°Ô µÈ´Ù. ¿©±â XML ¹®ÀÚ¿À» ¸ÅÇÎ ±¸¹®¿¡ ÆĶó¹ÌÅÍ·Î ³Ñ°ÜÁÖ´Â ¿¹Á¦°¡ ÀÖ´Ù.
String parameter = "
Account account = (Account) sqlMapClient.queryForObject(
"Account.getByXmlId",
parameter);
ºñ½ÁÇÑ ¹æ½ÄÀ¸·Î DOM °´Ã¼µµ µ¿ÀÏÇÑ °á°ú¸¦ ³¾ ¼ö ÀÖ°Ô iBATIS·Î ³Ñ°ÜÁÙ ¼ö ÀÖ´Ù.
Document parameterDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element paramElement = parameterDocument
.createElement("parameterDocument");
Element accountIdElement = parameterDocument
.createElement("accountId");
accountIdElement.setTextContent("3");
paramElement.appendChild(accountIdElement);
parameterDocument.appendChild(paramElement);
Account account = (Account) sqlMapClient.queryForObject(
"Account.getByXmlId", parameterDocument);
6.1.2 XML·Î °á°ú »ý¼ºÇϱâ
iBATIS ÇÁ·¹ÀÓ¿öÅ©´Â ¸ÅÇÎ ±¸¹®¿¡¼ XML·Î °á°ú¸¦ »ý¼ºÇÒ ¼öµµ ÀÖ´Ù. XMLÀ» ¹ÝȯÇϴ¸ÅÇÎ ±¸¹®À» ½ÇÇàÇÏ¸é °¢°¢ÀÇ ¹ÝȯµÈ °´Ã¼¸¦ ¿ÏÀüÇÑ XML ¹®¼·Î ¾òÀ» ¼ö ÀÖ´Ù.
ÀÌ ±â´ÉÀ» »ç¿ëÇϱâ À§ÇØ, °á°ú Ŭ·¡½º¸¦ ¡°xml¡±·Î ÁöÁ¤ÇÑ ¸ÅÇÎ ±¸¹®À» »ý¼ºÇÑ´Ù. ¿©±â°£´ÜÇÑ ¿¹Á¦°¡ ÀÖ´Ù.
String xmlData = (String) sqlMap.queryForObject(
"Account.getByIdValueXml",
new Integer(1));
ÀÌ °æ¿ì, ¹Ýȯ ¹ÞÀº °á°ú´Â ´ÙÀ½°ú °°´Ù.
XML ¹®¼·Î ³Ñ°Ü¹ÞÀº °á°ú°¡ ÇÑ °³ÀÇ ·¹Äڵ常À» °¡Áö°í ÀÖ´Ù¸é Á¤¸»·Î ´Ù·ç±â ½±´Ù. ¸¸ÀÏ ¿©·¯ °³ÀÇ °´Ã¼·Î ¹Þ±â¸¦ ¿øÇÑ´Ù¸é ±×·¸°Ô ÇÒ ¼öµµ ÀÖ´Ù. ¾Æ·¡¿¡ ¿¹Á¦°¡ ÀÖ´Ù.
List xmlList = sqlMap.queryForList("Account.getAllXml", null);
ÀÌ °æ¿ì °á°ú´Â XML ¹®¼ÀÇ ¸®½ºÆ®ÀÌ´Ù. ÀÌ·¸°Ô µÇ¸é ÇÑ °³ÀÇ XML¹®¼·Î ÇÕÄ¡±æ ¿øÇÒ °æ¿ì ¹®ÀÚ¿ ó¸® ÀÛ¾÷À» Çؾ߸¸ ÇÑ´Ù. ÀÌ°ÍÀº ÃÖÀûÀÇ ¹æ¹ýÀÌ ¾Æ´Ï´Ù.
ÀÌ ¹®Á¦¸¦ ÇÇÇØ°¡´Â ¹æ¹ýÀ¸·Î iBATIS°¡ °á°ú¸¦ XML·Î ¹ÝȯÇÏÁö ¾Ê°Ô ÇÏ´Â °ÍÀÌ´Ù. °£´ÜÇÑ ¹æ¹ýÀ¸·Î ´Ü¼øÇÑ Ä÷º¼ÇÀ» ¹ÝȯÇÏ´Â iBATISÀÇ ¸ÅÇÎ ±¸¹®À» »ç¿ëÇÏ°í ±×·ÎºÎÅÍ XMLÀ»»ý¼ºÇÏ´Â °ÍÀÌ´Ù. À̸¦ ¼öÇàÇÏ´Â ÇÑ °¡Áö °£´ÜÇÑ ¹æ¹ýÀ¸·Î(°á°ú·Î ºóÁ »ç¿ëÇÑ´Ù¸é)¾Æ·¡¿Í °°ÀÌ XML »ý¼ºÀ» µµ¿ÍÁÖ´Â ¸Þ¼µå¸¦ ¸¸µå´Â ¹æ¹ýÀÌ ÀÖ´Ù.
public String toXml(){
StringBuffer returnValue = new StringBuffer("");
returnValue.append("
returnValue.append("
returnValue.append("
returnValue.append("
returnValue.append("");
return returnValue.toString();
}
ÀÌ ¹®Á¦¿¡ ´ëÇÑ ¶Ç ´Ù¸¥ Á¢±Ù ¹æ¹ýÀ¸·Î ¸®Ç÷º¼ÇÀ» »ç¿ëÇÏ¿© ºóÁ XML·Î º¯È¯Çϴ Ŭ·¡½º¸¦ »ý¼ºÇÏ´Â ¹æ¹ýÀÌ ÀÖ´Ù. ÀÌ ¹æ¹ýÀº ¾ÆÁÖ °£´ÜÇÏ´Ù. ¾Æ·¡¿¡ ÀÌ ¹æ¹ýÀ» Àû¿ëÇÒ ¶§ »ç¿ëÇÒ ¼ö ÀÖ´Â ÀÛÀº À¯Æ¿¸®Æ¼°¡ ÀÖ´Ù.
public class XmlReflector {
private Class sourceClass;
private BeanInfo beanInfo;
private String name;
XmlReflector(Class sourceClass, String name) throws Exception {
this.sourceClass = sourceClass;
this.name = name;
beanInfo = Introspector.getBeanInfo(sourceClass);
}
public String convertToXml(Object o) throws Exception {
StringBuffer returnValue = new StringBuffer("");
if (o.getClass().isAssignableFrom(sourceClass)) {
PropertyDescriptor[] pd = beanInfo.getPropertyDescriptors();
if (pd.length > 0){
returnValue.append("<" + name + ">");
for (int i = 0; i < pd.length; i++) {
returnValue.append(getProp(o, pd[i]));
}
returnValue.append("");
} else {
returnValue.append("<" + name + "/>");
}
} else {
throw new ClassCastException("Class " + o.getClass().getName() +
" is not compatible with " + sourceClass.getName());
}
return returnValue.toString();
}
private String getProp(Object o, PropertyDescriptor pd)
throws Exception {
StringBuffer propValue = new StringBuffer("");
Method m = pd.getReadMethod();
Object ret = m.invoke(o);
if(null == ret){
propValue.append("<" + pd.getName() + "/>");
}else{
propValue.append("<" + pd.getName() + ">");
propValue.append(ret.toString());
propValue.append("");
}
return propValue.toString();
}
}
À§ ¿¹Á¦´Â ºóÁ ÆĶó¹ÌÅÍ·Î ¹Þ¾Æ¼ XML ¹®¼°¡ ¾Æ´Ñ XML ±¸¼º ¿ä¼Ò Á¶°¢À¸·Î º¯È¯ÇÑ´Ù. ¾Æ·¡¿¡ ¿¹Á¦°¡ ÀÖ´Ù.
XmlReflector xr = new XmlReflector(Account.class, "account");
xmlList = sqlMap.queryForList("Account.getAll", null);
StringBuffer sb = new StringBuffer(
"
for (int i = 0; i < xmlList.size(); i++) {
sb.append(xr.convertToXml(xmlList.get(i)));
}
sb.append("");
ÀÌ ±â¹ýÀ» »ç¿ëÇؼ ´ë¿ë·®ÀÇ ·¹Äڵ带 ó¸®ÇÏ´Â °ÍÀº ¸Þ¸ð¸® È¿À²¸é¿¡¼ ¸Å¿ì ÁÁÁö ¸øÇÏ´Ù. °´Ã¼ ¸®½ºÆ®¿Í XML ¹®¼¸¦ »ý¼ºÇϱâ À§ÇÑ ¹®ÀÚ¿ ¹öÆÛ¸¦ ¸Þ¸ð¸®»ó¿¡ ÀúÀåÇϱ⠶§¹®ÀÌ´Ù. 6.3Àý¿¡¼ ÀÌ ¿¹Á¦¸¦ ´Ù½Ã »ìÆ캸°í ´ë¿ë·®ÀÇ °á°ú¸¦ ó¸®ÇÏ´Â ´õ¿í È¿À²ÀûÀιæ¹ýÀ» ¾Ë¾Æº¼ °ÍÀÌ´Ù.
1.2. ¸ÅÇÎ ±¸¹®À» °´Ã¼¿Í ¿¬°ü½ÃÅ°±â
6.2.1 º¹ÀâÇÑ Ä÷º¼Ç(collection)
4Àå¿¡¼´Â SELECT ±¸¹®À» ÀÌ¿ëÇØ µ¥ÀÌÅÍ º£À̽º·ÎºÎÅÍ µ¥ÀÌÅ͸¦ °¡Á®¿À´Â ¹æ¹ýÀ» »ìÆ캸¾Ò´Ù. ±× ¿¹Á¦¿¡¼´Â ¿©·¯ Å×À̺íµéÀ» Á¶ÀÎÇÒ ¶§Á¶Â÷µµ °á°ú·Î´Â ´ÜÀÏ °´Ã¼ ŸÀÔ¸¸À»´Ù·ç¾ú´Ù. Á» ´õ º¹ÀâÇÑ °´Ã¼°¡ ÇÊ¿äÇÒ ¶§¿¡µµ iBATIS¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
ÀÌ·¯ÇÑ ±â´ÉÀº ¿©·¯ºÐÀÌ ¸¸µå´Â ¾ÖÇø®ÄÉÀ̼ÇÀÇ ¸ðµ¨ÀÌ µ¥ÀÌÅÍ ¸ðµ¨Ã³·³ º¸¿´À¸¸é ÇÒ¶§ À¯¿ëÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù. iBATIS¸¦ »ç¿ëÇÏ¿© ¿¬°üµÈ °´Ã¼µé¿¡ °üÇÑ µ¥ÀÌÅÍ ¸ðµ¨À» Á¤ÀÇÇÏ°í, iBATIS·Î ±× °´Ã¼µéÀ» ÇѲ¨¹ø¿¡ ÀоîµéÀÏ ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î Account ·¹Äڵ尡Order ·¹ÄÚµå¿Í ¿¬°üµÅ ÀÖ°í Order ·¹Äڵ尡 OrderItem ·¹ÄÚµå¿Í ¿¬°üµÅ ÀÖÀ» ¶§, ÀÌ·¯ÇÑ°ü°è¸¦ Á¤ÀÇÇÏ°í Account ¸¦ ¿äûÇÏ¸é ¸ðµç Order °´Ã¼¿Í ¸ðµç OrderItem °´Ã¼µé ¶ÇÇÑ °¡Á®¿Ã ¼ö ÀÖ´Ù.
ÀÌ·¯ÇÑ ÀÏÀ» ÇÒ ¼ö ÀÖ°Ô SQL MapÀ» Á¤ÀÇÇÏ´Â ¹æ¹ýÀº ¾Æ·¡¿Í °°´Ù.
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
class="org.apache.mapper2.examples.bean.AccountInfo">
column="accountId" />
select="Ch6.getOrderInfoList"
column="accountId" />
class="org.apache.mapper2.examples.bean.OrderInfo">
select="Ch6.getOrderItemList" />
class="org.apache.mapper2.examples.bean.OrderItem">
°á°ú ¸Ê(ResultAccountInfoMap (1), ResultOrderInfoMap (2), ResultOrderItemMap (3)À» º¸¸é óÀ½ µÎ °³´Â ¸ÅÇÎ ÇÁ·ÎÆÛƼ ÁßÀÇ Çϳª·Î select ¼Ó¼ºÀ» »ç¿ëÇÔÀ» º¼ ¼ö ÀÖ´Ù.
ÀÌ ¼Ó¼ºÀ» »ç¿ëÇϸé iBATIS´Â ÀÌ ÇÁ·ÎÆÛƼ°¡ select ¼Ó¼ºÀÇ °ªÀ¸·Î ÁöÁ¤µÈ ´Ù¸¥ ¸ÅÇÎ ±¸¹®ÀÇ ½ÇÇà °á°ú·Î ¼³Á¤µÈ´Ù°í °£ÁÖÇÏ°Ô µÈ´Ù. ¿¹¸¦ µé¾î getAccountInfoList ±¸¹® (4)À» ½ÇÇàÇÒ ¶§ °á°ú ¸Ê ResultAccountInfoMapÀº
ÀÌ ±â´ÉÀÌ °¡Áø Æí¸®ÇÔ¿¡µµ ºÒ±¸ÇÏ°í ÀÌ Á¢±Ù ¹æ½ÄÀº µÎ °¡Áö ¹®Á¦Á¡À» °¡Áö°í ÀÖ´Ù. ù°·Î ÀÌ ¹æ½ÄÀº ´ë¿ë·®ÀÇ ¸Þ¸ð¸®¸¦ ÇÊ¿ä·Î ÇÒ ¼öµµ ÀÖ´Ù. µÎ ¹ø°·Î ¾Æ·¡¿¡¼ ´Ù·ê ¡°N+1 Select ¹®Á¦¡±·Î ¾Ë·ÁÁø Çö»óÀ¸·Î ÀÎÇؼ µ¥ÀÌÅͺ£À̽º I/O ¹®Á¦¸¦ ÀÏÀ¸Å³ ¼ö ÀÖ´Ù. iBATIS ÇÁ·¹ÀÓ¿öÅ©´Â °¢ ¹®Á¦¿¡ ´ëÇÑ ÇØ°áÃ¥À» °¡Áö°í ÀÖ´Ù. ÇÏÁö¸¸ µÎ °¡Áö ¹®Á¦¸¦ ÇѲ¨¹ø¿¡ ÇØ°áÇÒ ¼ö´Â ¾ø´Ù.
- µ¥ÀÌÅÍ º£À̽º I/O
iBATIS °¡ Á¦°øÇϴ ij½Ì ¸ÅÄ¿´ÏÁòÀ» ¾ðÁ¦ ¾î¶»°Ô »ç¿ëÇÒÁö´Â 10Àå¿¡¼ »ìÆ캻´Ù.
¿¬°üµÈ µ¥ÀÌÅ͸¦ »ç¿ëÇÒ ¶§ ºÎµúÈ÷°Ô µÉ µ¥ÀÌÅͺ£À̽º I/O ¹®Á¦¸¦ »ìÆ캸±âÀ§ÇØ 1000°³ÀÇ °èÁÂ(Account)°¡ ÀÖ°í ±× °¢°¢ 1000°³ÀÇ ÁÖ¹®(Order)À» °¡Áö°í ÀÖÀ¸¸ç, ¶Ç °¢°¢ÀÇ ÁÖ¹®ÀÌ 25°³ÀÇ ÁÖ¹® Ç׸ñ(OrderItem)À» °¡Áö°í ÀÖ´Ù°í»ý°¢Çغ¸ÀÚ. ÀÌ ¸ðµç °ÍÀ» ¸Þ¸ð¸®¿¡ ÀûÀçÇÏ·Á µç´Ù¸é ÀÌ´Â 1000000 ȸ ÀÌ»óÀÇ SQL ¹®ÀåÀ» ½ÇÇàÇÏ°í ¾à 2500¸¸ °³ÀÇ ÀÚ¹Ù °´Ã¼¸¦ »ý¼ºÇÏ°Ô µÈ´Ù. ÀÌ·±ÀÏÀ» Çϸé Ʋ¸²¾øÀÌ ½Ã½ºÅÛ °ü¸®ÀÚ¿¡°Ô ÇÑ ¼Ò¸® µè°Ô µÉ °ÍÀÌ´Ù.
- ¡°N+1 Select¡± ¹®Á¦ »ìÆ캸±â
¡°N+1 Select¡± ¹®Á¦´Â ºÎ¸ð ·¹ÄÚµå ¸®½ºÆ®¿¡ ¿¬°üµÈ ÀÚ½Ä ·¹Äڵ带 ÀоîµéÀ϶§ ¹ß»ýÇÏ°Ô µÈ´Ù. ºÎ¸ð ·¹Äڵ带 °¡Á®¿À±â À§ÇØ ÇÑ °³ÀÇ Äõ¸®¸¦ ½ÇÇàÇϸéºÎ¸ð°¡ ¾î¶² ¼ö ¡°N¡± °³ ¸¸Å ÀÖ°ÔµÇ°í °¢ ºÎ¸ð ·¹Äڵ忡 ¿¬°üµÈ ÀÚ½Ä ·¹Äڵ带 ¾ò±â À§ÇØ ¡°N¡±¹øÀÇ Äõ¸®¸¦ ´õ ½ÇÇàÇØ¾ß ÇÑ´Ù. µû¶ó¼ ¡°N+1 Select¡± ¶ó´Â°á°ú¸¦ ¾ò´Â´Ù.
- À§ µÎ ¹®Á¦¿¡ ´ëÇÑ ÇØ°áÃ¥
ÀûÀç Áö¿¬(6.2.2 Àý¿¡¼ ¾Ë¾Æº¼ °ÍÀÌ´Ù.)Àº ÀûÀç ó¸® °úÁ¤À» °ü¸®Çϱâ ÁÁÀº¼öÁØÀ¸·Î ÀÛ°Ô ÂÉ°·À¸·Î½á ¸Þ¸ð¸® ¹®Á¦¸¦ ¿ÏȽÃÄÑÁØ´Ù. ±×·¯³ª ¿©ÀüÈ÷ µ¥ÀÌÅÍ º£À̽º I/O ¹®Á¦°¡ ³²¾ÆÀÖ´Ù.
µ¥ÀÌÅ͸¦ ÀÌ ¹æ½ÄÀ¸·Î ¿¬°ü ½Ãų ¶§ °èÁ¸¦ ÁÖ¹®¿¡, ÁÖ¹®À» ÁÖ¹® Ç׸ñ¿¡ ¿¬°ü½ÃÅ°´Â °ÍÀº °ú¿¬ ÁÁÀº ¿¹Á¦Àϱî? ÁÖ¹®°ú ÁÖ¹® Ç׸ñÀ» ¿¬°ü Áþ´Â °ÍÀº ÀûÀýÇÏ´Ù. ÇÏÁö¸¸ °èÁ¸¦ ÁÖ¹®°ú ¿¬°ü½ÃÅ°´Â °ÍÀº ±×´ÙÁö ½ÇÁúÀûÀÎ °ÍÀº ¸øµÈ´Ù.
ÇÏÁö¸¸ ÀÌ ¿¹Á¦´Â ¿ì¸®¿¡°Ô Ä£¼÷ÇÏ°í ÀÌÇØÇÒ ¼ö ÀÖ´Â °³³äÀ» »ç¿ëÇÏ¿© ¿©±â¼ ¹è¿ì°íÀÚ ÇÏ´Â ±â¹ýÀ» º¸¿©ÁÙ °ÍÀ̱⿡ ´çºÐ°£Àº ÀÌ ¿¹Á¦¸¦ »ç¿ëÇÒ °ÍÀÌ´Ù.
6.2.2 ÀûÀç Áö¿¬(lazy loading)
¸ÕÀú ¾Ë¾Æº¼ ÇØ°áÃ¥Àº ÀûÀç Áö¿¬ÀÌ´Ù. ÀûÀç Áö¿¬Àº ¸ðµç ¿¬°üµÈ µ¥ÀÌÅÍ°¡ Áï½Ã ÇÊ¿äÇÏÁö´Â ¾ÊÀº °æ¿ì¿¡ À¯¿ëÇÏ´Ù. ¿¹¸¦ µé¾î ¿ì¸®ÀÇ ¾ÖÇø®ÄÉÀ̼ÇÀÌ ¸ðµç °èÁ¸¦ º¸¿©ÁÖ´Â À¥ÆäÀÌÁö¿¡¼ È£ÃâµÇ°í, ÆǸŠ´ë¸®ÀÎÀÌ °èÁ¸¦ Ŭ¸¯ÇÏ¸é ±× °èÁÂÀÇ ¸ðµç ÁÖ¹®À» º¸°ÔµÇ°í,¸¶Áö¸·À¸·Î ƯÁ¤ ÁÖ¹®ÀÇ ¸ðµç ¼¼ºÎ ³»¿ªÀ» º¸±â À§ÇØ ÁÖ¹®À» Ŭ¸¯ÇÏ°Ô µÈ´Ù°í ÇÏÀÚ. ÀÌ·¯ÇÑ °æ¿ì ¿ì¸®¿¡°Ô ÇÊ¿äÇÑ °ÍÀº °¢ ½ÃÁ¡¿¡¼ ÇÑ °³ÀÇ ¸®½ºÆ® »ÓÀÌ´Ù. ÀÌ°ÍÀÌ ÀûÀç Áö¿¬ÀÇ ÀûÀýÇÑ »ç¿ë ¿¹ÀÌ´Ù.
ÀûÀç Áö¿¬À» »ç¿ëÇÏ·Á¸é SqlMapConfig.xml ÆÄÀÏÀ» ÆíÁýÇÏ¿©
6.2.3 N+1 Select ¹®Á¦ ÇÇÇØ°¡±â
¡°N+1 Select¡± ¹®Á¦¸¦ ÇÇÇØ°¥ ¼ö ÀÖ´Â ¹æ¹ýÀº µÎ °¡Áö°¡ ÀÖ´Ù. ÇÑ °¡Áö´Â iBATISÀÇ groupBy¼Ó¼ºÀ» »ç¿ëÇÏ´Â °ÍÀÌ°í ´Ù¸¥ ÇÑ°¡Áö´Â ·Î¿ì Çڵ鷯(Row Handler) ¶ó´Â »ç¿ëÀÚ Á¤ÀÇ ÄÄÆ÷³ÍÆ®¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù.
groupBy ¼Ó¼ºÀ» »ç¿ëÇÏ´Â °ÍÀº ¹Ù·Î Àü¿¡ ¾Ë¾Æº» ±â¹ý°ú ¸Å¿ì À¯»çÇÏ´Ù. °£´ÜÈ÷ ¸»Çؼ°á°ú ¸ÊÀ» »ç¿ëÇÏ¿© ¿¬°ü °ü°è¸¦ Á¤ÀÇÇÏ°í ÃÖ»óÀ§ °á°ú ¸ÊÀ» ¸ÅÇÎ ±¸¹®°ú °áÇÕ½ÃÅ°¸é µÈ´Ù. ¾Æ·¡ ¿¹Á¦´Â À§¿¡ ³ª¿Â ÀûÀç Áö¿¬ ¿¹Á¦¿Í ¿ÏÀüÈ÷ µ¿ÀÏÇÑ ±¸Á¶¸¦ »ý¼ºÇÏÁö¸¸ ¼¹ö¿¡¼´Â ´Ü ÇϳªÀÇ SQL ¹®À常ÀÌ ½ÇÇàµÈ´Ù.
¼¼ °¡ÁöÀÇ °á°ú ¸ÊÀÌ ¿¬°üµÅ Àִµ¥ Çϳª´Â °èÁÂ, ¶Ç Çϳª´Â ÁÖ¹® ±×¸®°í ³ª¸ÓÁö´Â ÁÖ¹®Ç׸ñÀ» À§ÇÑ °ÍÀÌ´Ù.
°èÁ¸¦ À§ÇÑ °á°ú ¸ÊÀº ¼¼ °¡Áö ±â´ÉÀ» ÇÑ´Ù.
l °è°ú °´Ã¼µéÀÇ ÇÁ·ÎÆÛƼ¸¦ ¸ÅÇÎÇÑ´Ù.
l iBATIS ¿¡°Ô ¾î¶² ÇÁ·ÎÆÛƼ°¡ »õ·Î¿î °èÁ¸¦ »ý¼ºÇϴµ¥ ÇÊ¿äÇÑÁö ¾Ë·ÁÁØ´Ù.
l iBATIS ¿¡°Ô ¿¬°üµÈ ´ÙÀ½ °´Ã¼ ¹À½À» ¾î¶»°Ô ¸ÅÇÎÇÒÁö ¾Ë·ÁÁִµ¥, ÀÌ °æ¿ì¿¡ ¿¬°üµÈ °´Ã¼ ¹À½À̶õ ÇØ´ç °èÁ¿¡ ¿¬°üµÈ ÁÖ¹® °´Ã¼ÀÇ ¹À½ÀÌ´Ù.
ÁÖÀÇÇØ¾ß ÇÒ ¸Å¿ì Áß¿äÇÑ »çÇ×ÀÌ Çϳª Àִµ¥, groupBy ¼Ó¼ºÀº ÇÁ·ÎÆÛƼÀÇ À̸§À» ÁöÁ¤ÇÏ´Â °ÍÀÌÁö Å×À̺í Ä®·³ À̸§À» ÁöÁ¤ÇÏ´Â °ÍÀÌ ¾Æ´Ï´Ù.
ÁÖ¹®À» À§ÇÑ °á°ú ¸Êµµ µ¿ÀÏÇÑ ¼¼ °¡Áö ±â´ÉÀ» °¡Áö°í ÀÖ´Ù.
l ÁÖ¹® µ¥ÀÌÅ͸¦ ÁÖ¹® °´Ã¼¿¡ ¸ÅÇÎÇÑ´Ù.
l ¾î¶² ÇÁ·ÎÆÛƼ°¡ »õ·Î¿î ÁÖ¹®À» °¡¸®Å°´ÂÁö ÁöÁ¤ÇÑ´Ù.
l ÀÚ½Ä ·¹ÄÚµåµéÀ» °¡Á®¿À±â À§ÇØ ¾î¶² °á°ú ¸ÊÀ» »ç¿ëÇÒÁö ÁöÁ¤ÇÑ´Ù.
¸¶Áö¸·À¸·Î ÁÖ¹® Ç׸ñ °á°ú ¸ÊÀº ±×³É ÀϹÝÀûÀÎ °á°ú ¸ÊÀ¸·Î ¿ÀÁ÷ ÁÖ¹® Ç׸ñÀ» °´Ã¼·Î¸ÅÇνÃÅ°´Â ¿ªÇÒ¸¸À» ÇÑ´Ù. ¾Æ·¡´Â ÀÌ¿¡ ´ëÇÑ ¸ÅÇÎ ¿¹Á¦ÀÌ´Ù.
class="AccountInfo"
groupBy="account.accountId" >
column="accountId" />
resultMap="Ch6.ResultOrderInfoNMap" />
class="OrderInfo"
groupBy="order.orderId" >
resultMap="Ch6.ResultOrderItemNMap" />
class="OrderItem">
column="orderId" />
column="orderItemId" />
¿ä¼Ò¿¡ ¹±â
resultMap="ResultAccountInfoNMap">
select
account.accountId as accountid,
orders.orderid as orderid,
orderitem.orderitemid as orderitemid
from account
join orders on account.accountId = orders.accountId
join orderitem on orders.orderId = orderitem.orderId
order by accountId, orderid, orderitemid
getAccountInfoListN ¸ÅÇÎ ±¸¹®À» È£ÃâÇÏ¿© (4) ¾ÕÀÇ µÎ ¿¹Á¦¿¡¼ º¸¿©ÁØ °Í°ú µ¿ÀÏÇÑ °á°ú µ¥ÀÌÅ͸¦ ¾ò°Ô µÈ´Ù. ÇÏÁö¸¸ ÀÌ °æ¿ì¿¡´Â ¿ÀÁ÷ ÇÑ °³ÀÇ SQL ¹®¸¸À» ½ÇÇàÇϱ⠶§¹®¿¡¾Õ ¿¹Á¦º¸´Ù ÈξÀ ºü¸£´Ù. ÀÌ°ÍÀº getAccoutnInfoListN ¸ÅÇÎ ±¸¹® (4)ÀÌ ½ÇÇàµÇ¸é ±× °á°ú´Â groupBy ¼Ó¼ºÀ» »ç¿ëÇÏ´Â resultAccountInfoNMap °á°ú ¸Ê (1)À» ÅëÇؼ ¸ÅÇÎÀ» ¼öÇàÇÏ¿© »ý¼ºµÈ´Ù. ÀÌ ¼Ó¼ºÀº iBATIS ¿¡°Ô account.accountId ÇÁ·ÎÆÛƼ°¡ º¯°æµÉ ¶§¿¡¸¸ »õ·Î¿îAccountInfo ÀνºÅϽº¸¦ »ý¼ºÇÏ¸é µÈ´Ù°í Áö½ÃÇÑ´Ù. Á» ´õ »ìÆ캸¸é orderList ÇÁ·ÎÆÛƼ°¡ ResultOrderInfoNMap °á°ú ¸Ê (2)¿Í ¸ÅÇÎÀÌ µÇ¾î Àֱ⠶§¹®¿¡ Äõ¸® °á°ú·Î ³ª¿Â ·¹Äڵ带 ó¸®ÇØ °¡¸é¼ ÁÖ¹® ¸®½ºÆ®µµ »ý¼ºÇÏ°Ô µÈ´Ù. ResultOrderInfoNMap °á°ú ¸Êµµ ¶ÇÇÑgroupBy ¼Ó¼ºÀ» »ç¿ëÇϱ⠶§¹®¿¡ orderItemList ÇÁ·ÎÆÛƼÀÇ ResultOrderItemNMap °á°ú¸Ê(3)À» ÀÌ¿ëÇÏ¿© orderItemList ¸¦ »ý¼ºÇÏ´Â °úÁ¤À» ¹Ýº¹ÇÒ °ÍÀÌ´Ù.
1.3. »ó¼Ó
6.3.1 »ó¼Ó ¸ÅÇÎÇϱâ
iBATIS´Â ±¸º°ÀÚ(discriminator) ¶ó°í ºÒ¸®´Â Ưº°ÇÑ ¸ÅÇÎÀ» »ç¿ëÇÏ¿© »ó¼Ó ±¸Á¶¸¦ Áö¿øÇÑ´Ù. ±¸º°ÀÚ¸¦ »ç¿ëÇÏ´Â °ÍÀ¸·Î µ¥ÀÌÅͺ£À̽ºÀÇ °ª¿¡ ±âÃÊÇÏ¿© °´Ã¼¸¦ »ý¼ºÇÒ Å¬·¡½ºÀÇŸÀÔÀ» ÆÇ´ÜÇÒ ¼ö ÀÖ´Ù. ±¸º°ÀÚ´Â °á°ú¸ÊÀÇ ÀϺÎÀÌ°í switch ±¸¹®Ã³·³ Àß ÀÛµ¿ÇÑ´Ù. ¿¹¸¦µé¸é:
À§ ±¸º°ÀÚ´Â ÀÌ·¸°Ô ÀÐÀ» ¼ö ÀÖ´Ù.
- Ä®·³ ¡°TYPE¡± ÀÌ ¡°Book¡± À̶ó´Â °ªÀ» Æ÷ÇÔÇÑ´Ù¸é, ¡°book¡± À̶ó´Â °á°ú¸ÊÀ» »ç¿ëÇ϶ó. ¹Ý¸é¿¡ Ä®·³ ¡°TYPE¡±ÀÌ ¡°Newspaper¡± ¶ó´Â °ªÀ» Æ÷ÇÔÇÑ´Ù¸é, ¡°news¡±¶ó´Â °á°ú¸ÊÀ» »ç¿ëÇ϶ó.
ÇÏÀ§ ¸ÊÀº À̸§À¸·Î ÂüÁ¶ÇÏ´Â ÀϹÝÀûÀÎ °á°ú¸ÊÀÌ´Ù. ±¸º°ÀÚ°¡ ÇÏÀ§ ¸Ê Áß Çϳª¿Í ÀÏÄ¡ÇÏ´Â °ªÀ» ãÁö ¸øÇÑ´Ù¸é, »óÀ§ °á°ú¸ÊÀÌ Àû¿ëµÈ´Ù. ÇÏÁö¸¸ ÀûÀýÇÑ °ªÀÌ ÀÖ´Ù¸é ¿ÀÁ÷ ÇÏÀ§¸Ê¸¸ÀÌ Àû¿ëµÈ´Ù. ºÎ¸ð¿¡ Á¤ÀÇµÈ °á°ú ¸ÅÇÎÀº ´ÙÀ½ ¿¹Á¦¿¡¼ º¸µíÀÌ ÇÏÀ§ ¸ÊÀÌ ºÎ¸ð ¸ÊÀ» ¸í½ÃÀûÀ¸·Î È®ÀåÇÏÁö ¾Ê´Â ÇÑ Àû¿ëµÇÁö ¾Ê´Â´Ù.
°á°ú¸ÊÀÇ extends ¼Ó¼ºÀº ÂüÁ¶ÇÏ´Â °á°ú¸Ê¿¡¼ ¸ðµç °á°ú ¸ÅÇÎÀ» È¿°úÀûÀ¸·Î º¹»çÇÑ´Ù.¾î·µç ÀÌ°ÍÀº Ŭ·¡½º ±¸Á¶¿¡ ´ëÇÑ ¾î¶°ÇÑ °Íµµ ÀǹÌÇÏÁö ¾Ê´Â´Ù. iBATIS´Â °´Ã¼ °ü°è ¸ÅÇÎ ÇÁ·¹ÀÓ¿öÅ©°¡ ¾Æ´Ï¶ó´Â °ÍÀ» ±â¾ïÇضó. ÀÌ Â÷ÀÌÁ¡Àº iBATIS°¡ Ŭ·¡½º¿Í µ¥ÀÌÅͺ£À̽º Å×ÀÌºí °£ÀÇ ¸ÅÇÎÀ» ¾Ë°Å³ª ´Ù·çÁö ¾Ê´Â´Ù´Â °ÍÀÌ´Ù.
1.4. Àâ´ÙÇÑ ´Ù¸¥ È°¿ë¹ýµé
6.4.1 statement ŸÀÔ°ú DDL »ç¿ëÇϱâ
select distinct
p.productId as productId,
o.accountId as accountId,
m.manufacturerId as manufacturerId
from product p
join manufacturer m
on p.manufacturerId = m.manufacturerId
join orderitem oi
on oi.productId = p.productId
join orders o
on oi.orderId = o.orderId
order by 1,2,3
AccountManufacturerProduct Ŭ·¡½º´Â ´Ü¼øÇÑ Å¬·¡½º·Î ¼¼ °¡Áö ÇÁ·ÎÆÛƼ(account, manufacturer, product)¸¦ °¡Áö°í ÀÖ´Ù. ÀÌ °á°ú ¸Ê(AmpRHExample)Àº µ¥ÀÌÅ͸¦ ÆòÆòÇϰԹٶ󺸴 ¹æ½ÄÀ¸·Î »ý¼ºÇÒ ¶§ ó·³ °¢ ÇÁ·ÎÆÛƼÀÇ °ªÀ» ÀÚµ¿À¸·Î ¼³Á¤ÇØÁØ´Ù.
ÀÌ ´ÙÀ½¿¡´Â ·Î¿ì Çڵ鷯°¡ ÀÌ °´Ã¼µéÀ» ¹Þ¾Æ¼ °´Ã¼¸¦ ¸¸³¯¶§¸¶´Ù À̸¦ productId, accountId, manufacturerId ¿¡ µû¶ó ¸Ê °´Ã¼·Î ºÐ·ùÇØ ³Ö´Â´Ù. °¢°¢ÀÇ account ȤÀºproduct¸¦ óÀ½À¸·Î ¹Þ¾ÆµéÀÏ ¶§ ÇØ´ç °´Ã¼¸¦ accountÀÇ ¸®½ºÆ®³ª productÀÇ ¸®½ºÆ®¿¡ °¢°¢ Ãß°¡ÇÑ´Ù. ¸¸¾à ¼±ÅÃµÈ °´Ã¼°¡ ÀÌ¹Ì ÀúÀåµÇ¾î ÀÖÀ» °æ¿ì, ÀÌ¹Ì (Map»ó¿¡) Á¸ÀçÇÏ´Â °´Ã¼°¡ µ¥ÀÌÅͺ£À̽º¿¡¼ ¹æ±Ý °¡Á®¿Â °´Ã¼¸¦ ´ëüÇÏ°Ô µÈ´Ù.
¸¶Áö¸·À¸·Î ƯÁ¤ account, manufacturer ȤÀº productÀÇ ´ÜÀÏ ÀνºÅϽº¸¦ ¿ÏÀüÈ÷ »ý¼ºÇѵڿ¡ À̸¦ ÀûÇÕÇÑ °´Ã¼¿¡ Ãß°¡ÇÏ°Ô µÈ´Ù. ÀÌ´Â ´ÙÀ½¿¡¼ º¼ ¼ö ÀÖ´Ù.
public class AMPRowHandler implements RowHandler {
private Map
= new HashMap
private Map
= new HashMap
private Map
= new HashMap
private List
= new ArrayList
private List
= new ArrayList
public void handleRow(Object valueObject) {
AccountManufacturerProduct amp;
amp = (AccountManufacturerProduct)valueObject;
Account currentAccount = amp.getAccount();
Manufacturer currentMfgr = amp.getManufacturer();
AccountManufacturers am;
ProductAccounts pa;
Product currentProduct = amp.getProduct();
if (null == accountMap.get(currentAccount.getAccountId())) {
// this is the first time we have seen this account
am = new AccountManufacturers();
am.setAccount(currentAccount);
accountMap.put(currentAccount.getAccountId(), am);
accountManufacturerList.add(am);
} else {
// Use the accoutn from the account map
am = accountMap.get(currentAccount.getAccountId());
currentAccount = am.getAccount();
}
// am is now the current account / manufacturerlist
if (null ==
manufacturerMap.get(currentMfgr.getManufacturerId())) {
// we have not seen this manufacturer yet
manufacturerMap.put(
currentMfgr.getManufacturerId(),
currentMfgr);
} else {
// we already have this manufacturer loaded, reuse it
currentMfgr = manufacturerMap.get(
currentMfgr.getManufacturerId());
}
am.getManufacturerList().add(currentMfgr);
if (null == productMap.get(currentProduct.getProductId())) {
// this is a new product
pa = new ProductAccounts();
pa.setProduct(currentProduct);
productMap.put(currentProduct.getProductId(), pa);
productAccountList.add(pa);
} else {
// this prodcut has been loaded already
pa = productMap.get(currentProduct.getProductId());
}
// pa is now the current product's product / account list
pa.getAccountList().add(currentAccount);
am.getManufacturerList().add(currentMfgr);
}
public List
return productAccountList;
}
public List
return accountManufacturerList;
}
public Map
return productMap;
}
public Map
return accountMap;
}
}
Äڵ尡 ²Ï º¹ÀâÇØ º¸À̱ä ÇÏÁö¸¸, ÀÌ Äڵ尡 ÇÏ´Â ÀÏ ¿ª½Ã ±²ÀåÈ÷ º¹ÀâÇϱ⠶§¹®¿¡ ¾î¿¼ö ¾ø´Ù.