1. 程式人生 > 其它 >解決mybatis一對多巢狀查詢,解決分頁資料少了的問題

解決mybatis一對多巢狀查詢,解決分頁資料少了的問題

轉載自: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
            }
        ]
    }
}