ibatis 对象关系实现

本文介绍了Ibatis在处理一对一及一对多关联查询时的方法,并详细解释了如何通过配置解决潜在的“n+1”Select性能问题。对于一对一关联,可以通过一次查询两张表的方式避免额外的查询开销;对于一对多关联,则可以通过使用内在的resultMap来优化。
hibernate 的强大在于完全的对象化,对于对象之间的关系解决的比较好,如1对1,1对多,多对1,以及多对多。当然也包括继承关系。
而ibatis这方面就比较逊色了,不过对于也支持简单的关连查询,如1对1,和1对多。对于一般的情况来说,这两种已经足够了,当然不能层叠更新是一个缺陷,看了半天文档,也没有找到对象之间的层叠更新,估计是不支持。
以前的版本ibatis处理关连是通过执行两次sql来实现的,如下的实例:
一对多关联:
xml 代码
  1. <sqlMapnamespace="User">
  2. <typeAliasalias="user"type="com.ibatis.sample.User"/>
  3. <typeAliasalias="address"type="com.ibatis.sample.Address"/>
  4. <resultMapid="get-user-result"class="user">
  5. <resultproperty="id"column="id"/>
  6. <resultproperty="name"column="name"/>
  7. <resultproperty="sex"column="sex"/>
  8. <resultproperty="addresses"column="id"select="User.getAddressByUserId"/>
  9. </resultMap>
  10. <selectid="getUsers"parameterClass="java.lang.String"resultMap="get-user-result">
  11. <![CDATA[</span></span></li> <li class="alt"><span><span class="cdata">selectid,name,sex</span></span></li> <li class=""><span><span class="cdata">fromt_user</span></span></li> <li class="alt"><span><span class="cdata">whereid=#id#</span></span></li> <li class=""><span><span class="cdata">]>
  12. </select>
  13. <selectid="getAddressByUserId"parameterClass="int"resultClass="address">
  14. <![CDATA[</span></span></li> <li class=""><span><span class="cdata">selectaddress,zipcode</span></span></li> <li class="alt"><span><span class="cdata">fromt_address</span></span></li> <li class=""><span><span class="cdata">whereuser_id=#userid#</span></span></li> <li class="alt"><span><span class="cdata">]>
  15. </select>
  16. </sqlMap>


这里通过在resultMap 中定义嵌套查询getAddressByUserId,我们实现了关联数据的读取。
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
xml 代码
  1. <resultMapid="get-user-result"class="user">
  2. <resultproperty="id"column="id"/>
  3. <resultproperty="name"column="name"/>
  4. <resultproperty="sex"column="sex"/>
  5. <resultproperty="address"column="t_address.address"/>
  6. <resultproperty="zipCode"column="t_address.zipcode"/>
  7. </resultMap>
  8. <selectid="getUsers"parameterClass="java.lang.String"resultMap="get-user-result">
  9. <![CDATA[</span></span></li> <li class="alt"><span><span class="cdata">select*</span></span></li> <li class=""><span><span class="cdata">fromt_user,t_address</span></span></li> <li class="alt"><span><span class="cdata">wheret_user.id=t_address.user_id</span></span></li> <li class=""><span><span class="cdata">]>
  10. </select>


在现在的版本中,对于n+1问题,ibatis已经很好的解决了。如下的配置:
一对一
xml 代码
  1. <resultMapid=”get-product-result”class=”com.ibatis.example.Product”>
  2. <resultproperty=”id”column=”PRD_ID”/>
  3. <resultproperty=”description”column=”PRD_DESCRIPTION”/>
  4. <resultproperty=”category”resultMap=“get-category-result”/>
  5. </resultMap>
  6. <resultMapid=”get-category-result”class=”com.ibatis.example.Category”>
  7. <resultproperty=”id”column=”CAT_ID”/>
  8. <resultproperty=”description”column=”CAT_DESCRIPTION”/>
  9. </resultMap>
  10. <selectid=”getProduct”parameterClass=”int”resultMap=”get-product-result”>
  11. select*
  12. fromPRODUCT,CATEGORY
  13. wherePRD_CAT_ID=CAT_ID
  14. andPRD_ID=#value#
  15. </select>

可以使用内在的resultMap来解决此问题。
同样一对多如下:
xml 代码
  1. <sqlMapnamespace="ProductCategory">
  2. <resultMapid=”categoryResult”class=”com.ibatis.example.Category”groupBy=”id”>
  3. <resultproperty=”id”column=”CAT_ID”/>
  4. <resultproperty=”description”column=”CAT_DESCRIPTION”/>
  5. <resultproperty=”productList”resultMap=”ProductCategory.productResult”/>
  6. </resultMap>
  7. <resultMapid=”productResult”class=”com.ibatis.example.Product”>
  8. <resultproperty=”id”column=”PRD_ID”/>
  9. <resultproperty=”description”column=”PRD_DESCRIPTION”/>
  10. </resultMap>
  11. <selectid=”getCategory”parameterClass=”int”resultMap=”categoryResult”>
  12. selectC.CAT_ID,C.CAT_DESCRIPTION,P.PRD_ID,P.PRD_DESCRIPTION
  13. fromCATEGORYC
  14. leftouterjoinPRODUCTP
  15. onC.CAT_ID=P.PRD_CAT_ID
  16. whereCAT_ID=#value#
  17. </select>
  18. </sqlMap>


注意,需要使用增加groupBy属性来分类
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值