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 () 的方法


比较三种方案各有适用范围:

第一种方案主要用于那些不需要一次取出主表和子表的数据,而是先取出主表数据,子表数据是通过更详细的查询一次次取出.
第二种方案 适合数据量比较少的主从表,一条语句取出所有数据
第三种方案 则通过两条select语句查询 在程序端组装结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值