您的位置:首页 > 其它

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

2012-09-11 21:05 253 查看
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上测试通过,更老旧的版本可能不支持该解决方案!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: