转自http://www.cnblogs.com/anderslly/archive/2007/12/27/ibatisinactionch062.html
java代码
public class T_User { private int user_id; private String group_id; private String user_name; private T_Group group; } public class T_Group { private int group_id; private String group_name; private List<T_Group_Privilege> group_p_id; } public class T_Group_Privilege { private int group_id; private int group_p_id; private String group_p_name; private T_Group group; }
这个是sqlMap.xml中的配置
<sqlMap> <typeAlias alias="T_User" type="org.ibiz.t3.beans.T_User" /> <typeAlias alias="T_Group" type="org.ibiz.t3.beans.T_Group" /> <typeAlias alias="T_Group_Privilege" type="org.ibiz.t3.beans.T_Group_Privilege" /> <resultMap id="T_UserresultMap" class="T_User"> <result property="user_id" column="user_id" /> <result property="user_name" column="user_name" /> <result property="group" column="group_id" select="getGroupId" /> </resultMap> <resultMap id="T_GroupresultMap" class="T_Group"> <result property="group_id" column="group_id" /> <result property="group_name" column="group_name" /> <result property="group_p_id" column="group_id" select="getTGP" /> </resultMap> <resultMap id="T_Group_PrivilegeresultMap" class="T_Group_Privilege"> <result property="group_id" column="group_id" /> <result property="group_p_name" column="group_p_name" /> <result property="group_p_id" column="group_p_id" /> </resultMap> <select id="getUser" resultMap="T_UserresultMap"> select * from T_User </select> <select id="getGroupId" resultMap="T_GroupresultMap" parameterClass="int"> select * from T_Group where group_id=#group_id# </select> <select id="getTGP" resultMap="T_Group_PrivilegeresultMap" parameterClass="int"> select * from T_Group_Privilege where group_id=#group_id# </select> </sqlMap>
只要调用getUser就可以了。
避免“N+1查询”问题
1.设置属性延迟加载
2.可以使用连接语句(Join)
简单的说,使用Result Map来定义对象间的关系,将顶层的Result Map关联到映射语句。下面的例子的Data Map文件结构与前面大体一致,但是只需要执行一条SQL语句。
这里面有三个Result Map,一是关于Account的,二是关于Order的,三是OrderItem的。
关于Account的Result Map有两个作用:
- 映射Account对象本身的属性。
- 告诉iBATIS如何映射下一层的关联对象,这里是orderList。
Order的Result Map作用与之类似。
- 映射Order对象本身的属性。
- 告诉iBATIS如何映射下一层的关联对象,这里是orderItemList。
<resultMap id="ResultAccountInfoNMap" class="AccountInfo"> <result property="account.accountId" column="accountId" /> <result property="orderList" resultMapping="Ch6.ResultOrderInfoNMap" /> </resultMap> <resultMap id="ResultOrderInfoNMap" class="OrderInfo"> <result property="order.orderId" column="orderId" /> <result property="orderItemList" resultMapping="Ch6.ResultOrderItemNMap" /> </resultMap> <resultMap id="ResultOrderItemNMap" class="OrderItem"> <result property="orderId" column="orderId" /> <result property="orderItemId" column="orderItemId" /> </resultMap> <select id="getAccountInfoListN" resultMap="ResultAccountInfoNMap"> select account.accountId as accountid, orders.orderid as orderid, orderitem.orderitemid as orderitemid from account inner join orders on account.accountId = orders.accountId inner join orderitem on orders.orderId = orderitem.orderId order by accountId, orderid, orderitemid </select>
延迟加载 |
Join |
如果要加载大量的数据,它们不会马上用到,延迟加载会比较合适。 |
数据量较小或者数据马上就会用到,Join方法比较合适。 |
译注:另外,我觉得还有一条很重要的原则,那就是永远只加载必需的数据。以上面的例子来说,我们不太可能会同时显示1000个Account给用户看,这时就不要同时加载1000个Account的数据了,可以通过分页只显示50条数据,在此基础上再应用延迟加载或Join效果会很不错。关于在Web项目中如何使用iBATIS进行分页