解決mybatis一對多巢狀查詢,解決分頁資料少了的問題
阿新 • • 發佈:2022-12-12
轉載自:https://blog.csdn.net/zjun1001/article/details/117671517
問題
在用mybatis做一對多查詢時候,常用collection配合完成結果查詢。在不涉及分頁查詢情況下,查詢結果是沒有問題的。但當涉及分頁查詢時,就會出現問題,即結果總數量total多於實際數量。
演示示例如下
實體類
@Data public class JudgePicPointSatatusResVo { private Integer id; private String judgePicPoint; private String productNum; private String judgePicStation; private String stationName; private List<String> stationNameList; private Integer status; }
Dao層
List<JudgePicPointSatatusResVo> getJudgePicPointListByJudgePicStationId(JudgePicPointSatatusReqVo judgePicPointSatatusReqVo);
查詢
<resultMap id="judgePicPointListMap" type="com.qxmz.vo.judgePic.JudgePicPointSatatusResVo"> <id column="id" property="id"/> <result column="judgePicPoint" property="judgePicPoint"/> <result column="productNum" property="productNum"/> <result column="judgePicStation" property="judgePicStation"/> <result column="status" property="status"/> <collection property="stationNameList" ofType="String"> <id column="stationName"/> </collection> </resultMap> <select id="getJudgePicPointListByJudgePicStationId" parameterType="com.qxmz.vo.judgePic.JudgePicPointSatatusReqVo" resultMap="judgePicPointListMap"> SELECT cj.`id`,cj.`productNum`,cj.`status`, jpp.`name` judgePicPoint,jps.`name` judgePicStation,st.station_name stationName FROM client_judgePicPoint cj LEFT JOIN judge_pic_point jpp ON cj.`judgePicPointId`=jpp.`id` LEFT JOIN judge_pic_station jps ON jpp.`judgePicStationId`=jps.`id` LEFT JOIN station st ON jps.`id`=st.`judgePicStationId` <where> cj.isAdd=1 <if test="judgePicStationIdList!=null"> and jps.id in <foreach item="judgePicStationId" collection="judgePicStationIdList" open="(" separator="," close=")"> #{judgePicStationId} </foreach> </if> <if test="status != null and status != 0"> and cj.status = #{status} </if> </where> </select>
結果
{ "code": 200, "message": "success", "data": { "total": 2, "rows": [ { "id": 2, "judgePicPoint": "判圖點3", "productNum": "002", "judgePicStation": "判圖站B", "stationName": "鄭州西站、南陽寨站", "stationNameList": [ "鄭州西站", "南陽寨站" ], "status": 2 } ] } }
從結果中可以看到,實際只查詢出來一條資料,但總數卻是2。這就是一對多分頁查詢會出現的問題。原因也很簡單,以上面資料為例。在mysql客戶端執行一對多SQL命令時,結果就是兩條。一對多情況下,mybatis會自動將結果裝備到collection中,但是在分頁情況下,mybatis會認為查詢的兩臺資料就是總的資料。
解決方法
採用父子查詢來實現,具體程式碼如下:
父查詢
<resultMap id="judgePicPointListMap" type="com.qxmz.vo.judgePic.JudgePicPointSatatusResVo"> <id column="id" property="id"/> <result column="judgePicPoint" property="judgePicPoint"/> <result column="productNum" property="productNum"/> <result column="judgePicStation" property="judgePicStation"/> <result column="status" property="status"/> <collection property="stationNameList" ofType="String" column="judgePicStationId" select="selectStationNameByJudgePicStationId"> </collection> </resultMap> <select id="getJudgePicPointListByJudgePicStationId" parameterType="com.qxmz.vo.judgePic.JudgePicPointSatatusReqVo" resultMap="judgePicPointListMap"> SELECT cj.`id`,cj.`productNum`,cj.`status`, jpp.`name` judgePicPoint,jps.`name` judgePicStation,jps.id judgePicStationId FROM client_judgePicPoint cj LEFT JOIN judge_pic_point jpp ON cj.`judgePicPointId`=jpp.`id` LEFT JOIN judge_pic_station jps ON jpp.`judgePicStationId`=jps.`id` <where> cj.isAdd=1 <if test="judgePicStationIdList!=null"> and jps.id in <foreach item="judgePicStationId" collection="judgePicStationIdList" open="(" separator="," close=")"> #{judgePicStationId} </foreach> </if> <if test="status != null and status != 0"> and cj.status = #{status} </if> </where> </select>
子查詢
<select id="selectStationNameByJudgePicStationId" resultType="String"> SELECT station_name FROM station WHERE judgePicStationId=#{judgePicStationId} </select>
正確結果
{ "code": 200, "message": "success", "data": { "total": 1, "rows": [ { "id": 2, "judgePicPoint": "判圖點3", "productNum": "002", "judgePicStation": "判圖站B", "stationName": "鄭州西站、南陽寨站", "stationNameList": [ "鄭州西站", "南陽寨站" ], "status": 2 } ] } }