Mybatis的Collection导致pageHelper分页失败

673 阅读1分钟

由于Collection嵌套结果方式会导致分页失败

解决方式 拆分sql 需要查询两次

<resultMap id="appDecisionDetailsMap" type="AppDecisionDetailDTO">
    <result column="application_id" property="applicationId" javaType="java.lang.String"/>
    <result column="application_name" property="applicationName" javaType="java.lang.String"/>
    <result column="bom_base_info_id" property="bomBaseInfoId" javaType="java.lang.String"/>
    <result column="bom_name" property="bomName" javaType="java.lang.String"/>
    <collection property="dimDetails" ofType="com.airong.adp.biz.dto.DimDetails"
                select="getDimDetailsByAppId" column="{applicationId=application_id}"/>
</resultMap>

使用collection标签实现嵌套查询,用到的属性总结如下:

1)select:另一个映射查询的id,MyBatis会额外执行这个查询获取嵌套对象的结果

2)column:将主查询中列的结果作为嵌套查询的参数,配置方式如column="{prop1=col1,prop2=col2}",prop1和prop2将作为嵌套查询的参数。

3)fetchType:数据加载方式,可选值为lazy和eager,分别为延迟加载和积极加载。

4)如果要使用延迟加载,除了将fetchType设置为lazy,还需要注意全局配置aggressiveLazyLoading的值应该为false。这个参数在3.4.5版本之前默认值为ture,从3.4.5版本开始默认值改为false。

<resultMap id="dimDetailsMap" type="DimDetails">
    <result column="dim_id" property="dimId" javaType="java.lang.String"/>
    <result column="dim_name" property="dimName" javaType="java.lang.String"/>
    <result column="dim_value" property="dimValue" javaType="java.lang.String"/>
    <result column="attr_name" property="dimValueName" javaType="java.lang.String"/>
    <result column="dim_attr" property="dimAttr" javaType="java.lang.String"/>
    <result column="dim_order" property="dimOrder" javaType="java.lang.String"/>
    <result column="code_service" property="codeService" javaType="java.lang.String"/>
    <result column="dim_class_path" property="dimClassPath" javaType="java.lang.String"/>
</resultMap>

原始sql

<select id="getApplicationDecisionDetails" resultMap="appDecisionDetailsMap">
SELECT DA.APPLICATION_ID,
       DA.APPLICATION_NAME,
       BBI.BOM_BASE_INFO_ID,
       BBI.BOM_NAME,
       DD.DIM_ID,
       DD.DIM_NAME,
       DD.DIM_CLASS_PATH,
       DD.DIM_ATTR,
       DD.CODE_SERVICE
FROM DECISION_APPLICATION DA
         LEFT JOIN BOM_BASE_INFO BBI ON DA.BOM_BASE_INFO_ID = BBI.BOM_BASE_INFO_ID
         LEFT JOIN DIM_DEFINED DD on DA.APPLICATION_ID = DD.APPLICATION_ID
</select>

拆分后的sql

执行过程是,先执行getApplicationDecisionDetails的查询,将application相关全都查询出来并进行分页,这种情况下分页是没问题的,然后再去查询每个应用对应的多条信息,走collection里的select查询,使用的条件是第一次查询结果中的主键id,然后他会自己查询信息封装到每个对应的application中,完成查询。

<select id="getApplicationDecisionDetails" resultMap="appDecisionDetailsMap">
    SELECT DA.APPLICATION_ID,
           DA.APPLICATION_NAME,
           BBI.BOM_BASE_INFO_ID,
           BBI.BOM_NAME
    FROM DECISION_APPLICATION DA
             LEFT JOIN BOM_BASE_INFO BBI ON DA.BOM_BASE_INFO_ID = BBI.BOM_BASE_INFO_ID
</select>

<select id="getDimDetailsByAppId" resultMap="dimDetailsMap">
    select DIM_ID,
           DIM_NAME,
           DIM_CLASS_PATH,
           DIM_ATTR,
           CODE_SERVICE
    FROM DIM_DEFINED
    WHERE APPLICATION_ID = #{applicationId}
    ORDER BY DIM_ID
</select>

拆分后mapper文件

List<AppDecisionDetailDTO> getApplicationDecisionDetails();

List<DimDetails> getDimDetailsByAppId(String applicationId);

参考以下两篇文章

blog.csdn.net/zwwhnly/art… blog.csdn.net/weixin_4512…