ibatis 对象关系实现

hibernate 的强大在于完全的对象化,对于对象之间的关系解决的比较好,如1对1,1对多,多对1,以及多对多。当然也包括继承关系。
    而ibatis这方面就比较逊色了,不过对于也支持简单的关连查询,如1对1,和1对多。对于一般的情况来说,这两种已经足够了,当然不能层叠更新是一个缺陷,看了半天文档,也没有找到对象之间的层叠更新,估计是不支持。
    以前的版本ibatis处理关连是通过执行两次sql来实现的,如下的实例:

    一对多关联:

<sqlMap namespace="User">  
<typeAlias alias="user" type="com.ibatis.sample.User"/>  
<typeAlias alias="address" type="com.ibatis.sample.Address"/>  
<resultMap id="get-user-result" class="user">  
<result property="id" column="id"/>  
<result property="name" column="name"/>  
<result property="sex" column="sex"/>  
<result property="addresses" column="id" select="User.getAddressByUserId"/>  
</resultMap>  
<select id="getUsers" parameterClass="java.lang.String" resultMap="get-user-result">  
<![CDATA[ 
select id,name,sex from t_user 
where id = #id# 
]]>  
</select>  
<select id="getAddressByUserId" parameterClass="int" resultClass="address">  
<![CDATA[ 
select address,zipcode 
from t_address 
where user_id = #userid# 
]]>  
</select>  
</sqlMap>
这里通过在resultMap 中定义嵌套查询getAddressByUserId,我们实现了关联数据的读取。
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
<resultMap id="get-user-result" class="user">  
<result property="id" column="id"/>  
<result property="name" column="name"/>  
<result property="sex" column="sex"/>  
<result property="address" column="t_address.address"/>  
<result property="zipCode" column="t_address.zipcode"/>  
</resultMap>  
<select id="getUsers" parameterClass="java.lang.String" resultMap="get-user-result">  
<![CDATA[ 
select * 
from t_user,t_address 
where t_user.id=t_address.user_id 
]]>  
</select>  
这里通过在resultMap 中定义嵌套查询getAddressByUserId,我们实现了关联数据的读取。
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
<resultMap id="get-user-result" class="user">  
<result property="id" column="id"/>  
<result property="name" column="name"/>  
<result property="sex" column="sex"/>  
<result property="address" column="t_address.address"/>  
<result property="zipCode" column="t_address.zipcode"/>  
</resultMap>  
<select id="getUsers" parameterClass="java.lang.String" resultMap="get-user-result">  
<![CDATA[ 
select * 
from t_user,t_address 
where t_user.id=t_address.user_id 
]]>  
</select>  

在现在的版本中,对于n+1问题,ibatis已经很好的解决了。如下的配置:
一对一

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>  
<result property=”id” column=”PRD_ID”/>  
<result property=”description” column=”PRD_DESCRIPTION”/>  
<result property=”category” resultMap=“get-category-result” />  
</resultMap>  
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>  
<result property=”id” column=”CAT_ID” />  
<result property=”description” column=”CAT_DESCRIPTION” />  
</resultMap>  
<select id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>  
select *  
from PRODUCT, CATEGORY  
where PRD_CAT_ID=CAT_ID  
and PRD_ID = #value#  
</select>
可以使用内在的resultMap来解决此问题。
同样一对多如下:

<sqlMap namespace="ProductCategory">  
<resultMap id=”categoryResult” class=”com.ibatis.example.Category” groupBy=”id”>  
<result property=”id” column=”CAT_ID”/>  
<result property=”description” column=”CAT_DESCRIPTION”/>  
<result property=”productList” resultMap=”ProductCategory.productResult”/>  
</resultMap>  
<resultMap id=”productResult” class=”com.ibatis.example.Product”>  
<result property=”id” column=”PRD_ID”/>  
<result property=”description” column=”PRD_DESCRIPTION”/>  
</resultMap>  
<select id=”getCategory” parameterClass=”int” resultMap=”categoryResult”>  
select C.CAT_ID, C.CAT_DESCRIPTION, P.PRD_ID, P.PRD_DESCRIPTION  
from CATEGORY C left outer join PRODUCT P  
on C.CAT_ID = P.PRD_CAT_ID  
where CAT_ID = #value#  
</select>  
</sqlMap>
注意,需要使用增加groupBy属性来分类
如果想实现,延迟加载的情况:

<sqlMapConfig> 
  <settings lazyLoadingEnabled="true"  

在日志中显示sql语句 

log4j.logger.com.ibatis=DEBUG 
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值