1.问题描述
使用Mybatis-Plus进行链表查询时,分页参数total和真实数据不一致
,Mybatis-Plus官方并没有提供对应的解决方案.经过查找资料,不断试验找到一种比较靠谱的解决方案;
2.解决思路
SQL语句中将关联的子表记录合并为一个json字符串作为一个字段存放到每条主表记录的后面,之后在Java代码中解析这个json字符串添加到对应集合类型字段中,这样既可以把关联的多条记录查询出来,又可以保证分页的正确性,而且还是支持条件查询;
3.案例
3.1.需求
将一个产品视频发布当前用户关联的商会中,查询的产品的时候需要关联的商会信息也查询出来;
3.2.具体实现
1>.Mapper接口
<E extends IPage<ProductVideoUnionInfoVO>> E queryMyProductVideoList(E page,ProductVideoReqVO reqVO);
2>.Mapper映射文件
<resultMap id="MINI_UNION_TABLE_MAP" type="xxx实体类">
<!--省略一大波属性与字段的映射-->
<result column="cocJson" property="cocInfos" typeHandler="com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler"/>
</resultMap>
<!--查询产品视频列表数据-->
<select id="queryMyProductVideoList" resultMap="MINI_UNION_TABLE_MAP">
SELECT
*
FROM
(
SELECT
<include refid="baseColumnList"></include>,
(
SELECT
CONCAT(
'[',
IFNULL(
GROUP_CONCAT(
CONCAT(
'{"id":',
CONCAT('"',zc.id,'"'),
',"name":',
CONCAT('"',zc.`name`,'"'),
'}'
) SEPARATOR ','
),
''
),
']'
)
FROM
zzy_coc zc
LEFT JOIN zzy_user_coc_product_video zucpv ON zucpv.coc_id = zc.id
AND zucpv.is_deleted = 0 AND zucpv.`status` = 1
WHERE
zpv.id = zucpv.pv_id
AND zpv.create_user = zucpv.user_id
) AS cocJson
FROM
zzy_product_video zpv
WHERE
zpv.`status` = 1
AND zpv.is_deleted = 0
<if test="reqVO.userId != null">
AND zpv.create_user = #{reqVO.userId}
</if>
<if test="reqVO.id != null">
AND zpv.id = #{reqVO.id}
</if>
ORDER BY zpv.is_top DESC , zpv.create_time DESC
) a
<where>
<if test="reqVO.cocId != null">
<![CDATA[
JSON_CONTAINS(a.cocJson->'$[*].id',CONCAT('"',#{reqVO.cocId},'"'))
]]>
</if>
</where>
</select>
4.总结
使用这种方案可以处理分页Bug,但是建议在"多"的一方数据量比较少
的情况下使用!