IBatis学习关于N+1问题的解决

来源:互联网 发布:免费图片库 知乎 编辑:程序博客网 时间:2024/05/19 18:12

N+1查询问题是由于加载父记录列表的相关子记录而造成的。因此,如果执行一条查询语句并获取N条父记录,那么为了获取这些父记录的字记录,就必须再执行N个查询,这就产生了N+1的问题。

 

 

解决方法一 表连接查询使用groupBy属性:

Subject.xml:pojo类Subject中有属性List<Option> optionList;

 

<resultMap id="subjectjoin" class="subject" groupBy="subjectId">
  <result property="subjectId" column="subjectId" />
  <result property="subjectName" column="subjectName" />
  <result property="subjectType" column="subjectType" />
  <result property="subjectStatus" column="subjectStatus" />
  <result property="fpaperId" column="FPaperId" />
  <result property="optionList" resultMap="Subject.optionList" />
 </resultMap>
 <resultMap id="optionList" class="options">
  <result property="optionsId" column="OptionsId" />
  <result property="options" column="Options" />
  <result property="fsubjectId" column="FSubject" />
 </resultMap>
 
 <select id="getOneSubjectByIdJoin" resultMap="subjectjoin" parameterClass="java.lang.Integer">
  select subjectId,subjectName,subjectType,subjectStatus,FPaperId,OptionsId,Options,FSubject from subject s,options op where op.fsubject=s.subjectid and s.SubjectId=#value#
 </select>

 

解决方法一 延迟加载:

sqlmapconfig.xml里面将<setting>元素的lazyloadingEnabled设为true;使用select属性

Subject.xml:

 

<resultMap id="subjectLazy" class="subject" >
  <result property="subjectId" column="subjectId" />
  <result property="subjectName" column="subjectName" />
  <result property="subjectType" column="subjectType" />
  <result property="subjectStatus" column="subjectStatus" />
  <result property="fpaperId" column="FPaperId" />
  <result property="optionList" column="subjectId" select="Options.queryOneSubject"/>
 </resultMap>
 
 
 <select id="getOneSubjectByIdLazy" resultMap="subjectLazy" parameterClass="java.lang.Integer">
  select subjectId,subjectName,subjectType,subjectStatus,FPaperId from subject where SubjectId=#value#
 </select>

Options.xml:

 

 <select id="queryOneSubject" resultClass="options" parameterClass="java.lang.Integer">
  select OptionsId,Options,FSubject from Options where FSubject=#value#
 </select>

 

延迟加载只有需要使用Options的时候才会执行Options.queryOneSubject,是将加载的过程分割成更小更易管理的小过程,查询的时机不一样只有当使用的时候才查询,从一定程度上解决的N+1,使其变成1+1,当然如果要一次性的显示所有的的结果延迟加载还是要执行N+1次查询。而表连接查询则会一次性把所有的Options查询出来虽然只有一条查询语句,但记录的条数不变,虽然表连接解决了N+1问题但是并没有解决大型数据集的问题,内存中还是会加载这么多记录条数。

原创粉丝点击