各位小伙伴在使用过 pageHelper 分页插件神器的话应该有和小弟同样的经历 , 在使用 一对多标签的时候 , 会导致数据错乱 !
这里使用一个简单的业务场景 , 一个用户 下了多个订单 , 一个user 对应多个 order ;
映射对象如下:
查询sql 如下 :
可是查询出来的结果却如下 :
明明设置了 分页 5条数据 , 查出来的却只有2条list结果集合 ;
原因分析 : 查询的sql 确实是查出来了5条数据, 只是 框架 , 把 多条数据 , 封装在了 user 里面的 orderList 里面 , 这就是 一对多 的查询场景 , pageHelper 插件 只会把总记录数分页 , 因此呢 , 会出现 , 一对多查询, pageHelper 插件 会出现分页错乱情况 ;
有两种解决方案:
方案01 , 使用mybatis 的子查询 来解决 , **在 标签中使用 select , column 属性 开启子查询 **
本人的sql.xml如下 ,
<resultMap id="userMap" type="com.xwd.entity.User">
<id column="uid" property="uid"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
<!--
一对多关联 collection标签
property="orderList" 关联实体集合的属性名
ofType="com.xwd.entity.Order" 关联实体的java类型(集合泛型的类型)
select="selectOrder" 指定子查询
column="uid" 向子查询传递 参数, 参数从主查询的结果中获取!!!
-->
<collection property="orderList" ofType="com.xwd.entity.Order" select="selectOrder" column="uid">
<id column="oid" property="oid"></id>
<result column="ordertime" property="ordertime"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<!--一对多关联-->
<select id="findUserByIdWithOrders" resultMap="userMap">
SELECT * FROM `user` u
</select>
<!--子查询-->
<select id="selectOrder" resultType="com.xwd.entity.Order" parameterType="string">
select * from orders o where o.uid = #{uid}
</select>
这样改完后, 查询的过程就会变成 , 先按照分页的规则 查询 出有几个 user , 然后拿 user中的 uid 去 order 表 中查, 并且查出来的结果, 会自动封装在 user 中的 list 集合中 , 但是有一点不好, 就是对多次触发子查询对性能不友好 ;
方案02 , 就是先分页查询出user的id , 再拿着userid 去查订单表 , 分开两次查询 ;
以上就是我做分页踩的一个坑 , 做一对多并且使用 标签的分页查询的老铁们 , 不出意外有可能会遇到和我一样的bug , 最后希望能帮助到大家