hibernate 的强大在于完全的对象化,对于对象之间的关系解决的比较好,如1对1,1对多,多对1,以及多对多。当然也包括继承关系。
而ibatis这方面就比较逊色了,不过对于也支持简单的关连查询,如1对1,和1对多。对于一般的情况来说,这两种已经足够了,当然不能层叠更新是一个缺陷,看了半天文档,也没有找到对象之间的层叠更新,估计是不支持。
以前的版本ibatis处理关连是通过执行两次sql来实现的,如下的实例:
一对多关联:
这里通过在resultMap 中定义嵌套查询getAddressByUserId,我们实现了关联数据的读取。
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
在现在的版本中,对于n+1问题,ibatis已经很好的解决了。如下的配置:
一对一
可以使用内在的resultMap来解决此问题。
同样一对多如下:
注意,需要使用增加groupBy属性来分类
而ibatis这方面就比较逊色了,不过对于也支持简单的关连查询,如1对1,和1对多。对于一般的情况来说,这两种已经足够了,当然不能层叠更新是一个缺陷,看了半天文档,也没有找到对象之间的层叠更新,估计是不支持。
以前的版本ibatis处理关连是通过执行两次sql来实现的,如下的实例:
一对多关联:
xml 代码
- <sqlMapnamespace="User">
- <typeAliasalias="user"type="com.ibatis.sample.User"/>
- <typeAliasalias="address"type="com.ibatis.sample.Address"/>
- <resultMapid="get-user-result"class="user">
- <resultproperty="id"column="id"/>
- <resultproperty="name"column="name"/>
- <resultproperty="sex"column="sex"/>
- <resultproperty="addresses"column="id"select="User.getAddressByUserId"/>
- </resultMap>
- <selectid="getUsers"parameterClass="java.lang.String"resultMap="get-user-result">
- <![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">]>
- </select>
- <selectid="getAddressByUserId"parameterClass="int"resultClass="address">
- <![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">]>
- </select>
- </sqlMap>
这里通过在resultMap 中定义嵌套查询getAddressByUserId,我们实现了关联数据的读取。
需要注意的是,这里有一个潜在的性能问题,也就是所谓“n+1”Select问题。
一对一关联:
对于这种情况,我们可以采用一次Select两张表的方式,避免这样的性能开销(假设上面示例中,每个User 只有一个对应的Address记录):
xml 代码
- <resultMapid="get-user-result"class="user">
- <resultproperty="id"column="id"/>
- <resultproperty="name"column="name"/>
- <resultproperty="sex"column="sex"/>
- <resultproperty="address"column="t_address.address"/>
- <resultproperty="zipCode"column="t_address.zipcode"/>
- </resultMap>
- <selectid="getUsers"parameterClass="java.lang.String"resultMap="get-user-result">
- <![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">]>
- </select>
在现在的版本中,对于n+1问题,ibatis已经很好的解决了。如下的配置:
一对一
xml 代码
- <resultMapid=”get-product-result”class=”com.ibatis.example.Product”>
- <resultproperty=”id”column=”PRD_ID”/>
- <resultproperty=”description”column=”PRD_DESCRIPTION”/>
- <resultproperty=”category”resultMap=“get-category-result”/>
- </resultMap>
- <resultMapid=”get-category-result”class=”com.ibatis.example.Category”>
- <resultproperty=”id”column=”CAT_ID”/>
- <resultproperty=”description”column=”CAT_DESCRIPTION”/>
- </resultMap>
- <selectid=”getProduct”parameterClass=”int”resultMap=”get-product-result”>
- select*
- fromPRODUCT,CATEGORY
- wherePRD_CAT_ID=CAT_ID
- andPRD_ID=#value#
- </select>
可以使用内在的resultMap来解决此问题。
同样一对多如下:
xml 代码
- <sqlMapnamespace="ProductCategory">
- <resultMapid=”categoryResult”class=”com.ibatis.example.Category”groupBy=”id”>
- <resultproperty=”id”column=”CAT_ID”/>
- <resultproperty=”description”column=”CAT_DESCRIPTION”/>
- <resultproperty=”productList”resultMap=”ProductCategory.productResult”/>
- </resultMap>
- <resultMapid=”productResult”class=”com.ibatis.example.Product”>
- <resultproperty=”id”column=”PRD_ID”/>
- <resultproperty=”description”column=”PRD_DESCRIPTION”/>
- </resultMap>
- <selectid=”getCategory”parameterClass=”int”resultMap=”categoryResult”>
- selectC.CAT_ID,C.CAT_DESCRIPTION,P.PRD_ID,P.PRD_DESCRIPTION
- fromCATEGORYC
- leftouterjoinPRODUCTP
- onC.CAT_ID=P.PRD_CAT_ID
- whereCAT_ID=#value#
- </select>
- </sqlMap>
注意,需要使用增加groupBy属性来分类
本文介绍了Ibatis在处理一对一及一对多关联查询时的方法,并详细解释了如何通过配置解决潜在的“n+1”Select性能问题。对于一对一关联,可以通过一次查询两张表的方式避免额外的查询开销;对于一对多关联,则可以通过使用内在的resultMap来优化。
688

被折叠的 条评论
为什么被折叠?



