Mybatis-Plus分页插件,嵌套查询和嵌套结果映射

Mybatis-Plus分页插件注意事项

使用Mybatis-Plus的分页插件进行分页查询时,如果结果需要使用<collection>进行映射,只能使用嵌套查询(Nested Select for Collection),而不能使用嵌套结果映射(Nested Results for Collection)

嵌套查询嵌套结果映射是Collection映射的两种方式,下面通过一个案例进行介绍

例如有room_infograph_info两张表,其关系为一对多,如下
image

现需要查询房间列表及其图片信息,期望返回的结果如下

[
    {
        "id": 1,
        "number": 201,
        "rent": 2000,
        "graphList": [
            {
                "id": 1,
                "url": "http://",
                "roomId": 1
            },
            {
                "id": 2,
                "url": "http://",
                "roomId": 1
            }
        ]
    },
    {
        "id": 2,
        "number": 202,
        "rent": 3000,
        "graphList": [
            {
                "id": 3,
                "url": "http://",
                "roomId": 2
            },
            {
                "id": 4,
                "url": "http://",
                "roomId": 2
            }
        ]
    }
]

为得到上述结果,可使用以下两种方式

  • 嵌套结果映射

    <select id="selectRoomPage" resultMap="RoomPageMap">
        select ri.id room_id,
               ri.number,
               ri.rent,
               gi.id graph_id,
               gi.url,
               gi.room_id
        from room_info ri
           left join graph_info gi on ri.id=gi.room_id
    </select>
    
    <resultMap id="RoomPageMap" type="RoomInfoVo" autoMapping="true">
        <id column="room_id" property="id"/>
        <collection property="graphInfoList" ofType="GraphInfo" autoMapping="true">
            <id column="graph_id" property="id"/>
        </collection>
    </resultMap>
    

    这种方式的执行原理如下图所示

image

  • 嵌套查询

    <select id="selectRoomPage" resultMap="RoomPageMap">
        select id,
               number,
               rent
        from room_info
    </select>
    
    <resultMap id="RoomPageMap" type="RoomInfoVo" autoMapping="true">
        <id column="id" property="id"/>
        <collection property="graphInfoList" ofType="GraphInfo" select="selectGraphByRoomId"                      column="id"/>
    </resultMap>
    
    <select id="selectGraphByRoomId" resultType="GraphInfo">
        select id,
               url,
               room_id
        from graph_info
        where room_id = #{id}
    </select>
    

    这种方法使用两个独立的查询语句来获取一对多关系的数据。首先,Mybatis会执行主查询来获取room_info列表,然后对于每个room_info,Mybatis都会执行一次子查询来获取其对应的graph_info。执行n+1次,n是主表的行数。

image

若现在使用MybatisPlus的分页插件进行分页查询,假如查询的内容是第1页,每页2条记录,(应该查出两条房间记录,房间表是主表),则上述两种方式的查询结果分别是

  • 嵌套结果映射
    image

  • 嵌套查询
    image

显然嵌套结果映射的分页逻辑是存在问题的。

posted @ 2024-06-23 15:40  r1-12king  阅读(195)  评论(0编辑  收藏  举报