技术类 Mybatis Mybatis 关联嵌套查询时分页异常的解决思路 双木老林 2020-06-05 2021-03-09 问题 当出现嵌套关系,且嵌套关系为 一对多 的时候,分页会出现异常,大致原因就是想分的是 一 的数据,但是实际上分的是 多 的数据。
案例 实体 1 2 3 4 5 @lombok .EqualsAndHashCode(callSuper = true )@lombok .Datapublic class UserVo extends User { private List<Order> orders; }
1 2 3 4 5 @lombok .Datapublic class User { private Integer userId; private String userName; }
1 2 3 4 5 6 @lombok .Datapublic class Order { private Integer orderId; private Integer userId; private String orderName; }
通过 的 select 标签 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <resultMap id ="UserResultMap" type ="com.example.demo.pojo.User" > <id column ="user_id" jdbcType ="INTEGER" property ="userId" /> <result column ="user_name" jdbcType ="VARCHAR" property ="userName" /> </resultMap > <resultMap id ="OrderResultMap" type ="com.example.demo.pojo.Order" > <id column ="order_id" jdbcType ="INTEGER" property ="orderId" /> <result column ="order_name" jdbcType ="VARCHAR" property ="orderName" /> </resultMap > <resultMap id ="UserVoResultMap" type ="com.example.demo.pojo.vo.UserVo" > <id column ="user_id" jdbcType ="INTEGER" property ="userId" /> <result column ="user_name" jdbcType ="VARCHAR" property ="userName" /> <collection property ="orders" ofType ="com.example.demo.pojo.Order" select ="selectOrder" column ="{userId=user_id}" /> </resultMap > <select id ="selectVo" resultMap ="UserVoResultMap" > select user_id, user_name from t_user </select > <select id ="selectOrder" resultMap ="OrderResultMap" > select order_id, order_name from t_order where user_id = #{userId} </select >
缺点:
User 查出了多少条记录, 就得查多少次 Order
正常手段没法使用 Order 的查询条件
另一种方式 后面因为产品里一页的记录数正常是 50,就导致效率很低,后面头脑风暴了一下,就多了这种方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <resultMap id ="UVoResultMap" type ="com.example.demo.pojo.vo.UserVo" > <id column ="user_id" jdbcType ="INTEGER" property ="userId" /> <result column ="user_name" jdbcType ="VARCHAR" property ="userName" /> <collection property ="orders" ofType ="com.example.demo.pojo.Order" > <id column ="order_id" jdbcType ="INTEGER" property ="orderId" /> <result column ="order_name" jdbcType ="VARCHAR" property ="orderName" /> </collection > </resultMap > <select id ="selectPage" parameterType ="Object" resultMap ="UVoResultMap" > SELECT v.user_id, v.user_name, v.order_id, v.order_name FROM ( SELECT u.user_id, u.user_name, o.order_id, o.order_name FROM t_user u LEFT JOIN t_order o ON u.user_id = o.user_id <where ...... > ) v JOIN ( SELECT DISTINCT u.user_id FROM t_user u LEFT JOIN t_order o ON u.user_id = o.user_id <where ...... > LIMIT 0, 50 ) d USING ( user_id ) </select >
缺点就是将语句查多了一次,但总比 50 次好,如果有更优的办法,可以给我留言,或者我自己悟了我再加上。