hibernate 的强大在于完全的对象化,对于对象之间的关系解决的比较好,如1对1,1对多,多对1,以及多对多。当然也包括继承关系。
而ibatis这方面就比较逊色了,不过对于也支持简单的关连查询,如1对1,和1对多。对于一般的情况来说,这两种已经足够了,当然不能层叠更新是一个缺陷,看了半天文档,也没有找到对象之间的层叠更新,估计是不支持。
以前的版本ibatis处理关连是通过执行两次sql来实现的,如下的实例:
一对多关联:
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
同样一对多如下:
而ibatis这方面就比较逊色了,不过对于也支持简单的关连查询,如1对1,和1对多。对于一般的情况来说,这两种已经足够了,当然不能层叠更新是一个缺陷,看了半天文档,也没有找到对象之间的层叠更新,估计是不支持。
以前的版本ibatis处理关连是通过执行两次sql来实现的,如下的实例:
一对多关联:
这里通过在resultMap 中定义嵌套查询getAddressByUserId,我们实现了关联数据的读取。< 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[ <! [CDATA[ </ span > </ span ></ li > < li class = " alt " >< span >< span class = " cdata " >
select id,name,sex </ span > </ span ></ li > < li class = "" >< span >< span class = " cdata " > from t_user
</ span > </ span ></ li > < li class = " alt " >< span >< span class = " cdata " > where id = #id# </ span >
</ span ></ li > < li class = "" >< span >< span class = " cdata " > ] ></ select >
< select id = " getAddressByUserId " parameterClass = " int " resultClass = " address " >
<! [CDATA[ <! [CDATA[ </ span > </ span ></ li > < li class = "" >< span >< span class = " cdata " >
select address,zipcode </ span > </ span ></ li > < li class = " alt " >< span >< span class = " cdata " >
from t_address </ span > </ span ></ li > < li class = "" >< span >< span class = " cdata " >
where user_id = #userid# </ span > </ span ></ li > < li class = " alt " >< span >< span class = " cdata " > ] ></ select >
</ sqlMap >
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
在现在的版本中,对于n+1问题,ibatis已经很好的解决了。如下的配置:< 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[ <! [CDATA[ </ span > </ span ></ li > < li class = " alt " >< span >< span class = " cdata " >
select *</ span > </ span ></ li > < li class = "" >< span >< span class = " cdata " > from t_user,t_address
</ span > </ span ></ li > < li class = " alt " >< span >< span class = " cdata " >
where t_user.id = t_address.user_id </ span > </ span ></ li > < li class = "" >< span >
< span class = " cdata " > ] ></ select >
可以使用内在的resultMap来解决此问题。< 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 >
同样一对多如下:
注意,需要使用增加groupBy属性来分类< 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 >