Ibatis解决N+1的方案及优缺点

ibatis n+1选择问题 的几种解决方案 
n+1选择问题定义: 
The N+1 Selects problem is caused by trying to load child records that are related to a list of parent records. 
在ibatis里有三种解决方案 
1 Lazy loading 
2避免N+1 Select 
3通过两条select语句分别从两个表中取数据然后组装 

1 Lazy loading: 
首先要设置 lazyLoadingEnabled="true" 
其次 在map中 注意 
<resultMap id="flightandPriceDO" 
   class="com.taobao.et.biz.dal.core.dataobject.FlightInfoDO"> 
   <result property="id" column="id" jdbcType="NUMBER" /> 
   ........ 
   <result property="priceinfos" column="id" 
     select="FlightInfoDO.getPriceinfosbyflightid" /> 
</resultMap> 
select语句同一张表的一样。 
<select id="getFlightInfowithprices" resultMap="flightandPriceDO"> 
<![CDATA[ 
select 
id, 
STANDARD_PRICE 
from FLIGHT_RESULT 
where DEP_AIRPORT_CODE= #depairport.airportcode# 
and ARR_AIRPORT_CODE=#arrairport.airportcode# 
]]> 
</select> 
<select id="getPriceinfosbyflightid" parameterClass="java.lang.Long" 
resultMap="cabinpriceDO"> 
<![CDATA[ 
select 
id, 
FLIGHTID, 
from cabin_price 
where FLIGHTID=#value# 
and cabin_number!='0' 
]]> 
</select> 

2避免N+1 Select 
主要在于 修改mapping文件 
以及select语句 
<resultMap id="flightandPriceDOavoidn1" 
   class="com.taobao.et.biz.dal.core.dataobject.FlightInfoDO" groupBy="id"> 
   <result property="id" column="id" jdbcType="NUMBER" /> 
   <result property="depAirport.airportcode" 
     column="DEP_AIRPORT_CODE" jdbcType="VARCHAR2" /> 
   <result property="priceinfos" resultMap="FlightInfoDO.cabinpriceDO" /> 
</resultMap> 
<resultMap id="cabinpriceDO" 
class="com.taobao.et.biz.dal.core.dataobject.CabinPriceDO"> 
<result property="id" column="id" jdbcType="number" /> 
<result property="flightID" column="FLIGHTID" jdbcType="number" /> 
</resultMap> 
<select id="getFlightInfowithpricesavoidn1" resultMap="flightandPriceDOavoidn1"> 
<![CDATA[ 
select * 
from FLIGHT_RESULT a join cabin_price b on   a.id=b.FLIGHTID 
where a.DEP_AIRPORT_CODE= #depairport.airportcode# 
and a.ARR_AIRPORT_CODE=#arrairport.airportcode# 
order by a.id,b.FLIGHTID 
]]> 
</select> 

3通过两条select语句分别从两个表中取数据然后组装 
主要是子表必须提供一种 select * from zibiao in () 的方法 

比较 
三种方案各有适用范围 
第一种方案主要用于那些 不需要一次取出主表和子表的数据,而是先取出主表数据,子表数据是通过ui一次次取 
第二种方案 适合数据量比较少的主从表,一条语句取出所有数据 

第三种方案 则通过两条select语句查询 在程序端组装结果


原文地址:

http://hi.baidu.com/tingshu99/item/40a9aa3a7994165f81f1a7b4


个人补充:

注意这个配置:<result property="" resultMap="namespace.xxx" />,resultMap是namespace.xxx,要加命名空间,,否则iBATIS可能会报错! 

2. 一对多/多对多映射的集合属性subMenus必须用简单的getter/setter,不能在getter/setter里做其他处理,否则会导致iBATIS报错!! 

3. 在iBATIS2.3.0.677上测试通过,更老旧的版本可能不支持该解决方案!! 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值