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问题但是并没有解决大型数据集的问题,内存中还是会加载这么多记录条数。