pagehelper导致一对多查询分页出错

本文探讨了使用PageHelper进行MyBatis一对多查询时分页出现的问题及原因,一对多collection按多计算导致分页错误。提供了解决方案,包括修改为collection的select子查询和自定义分页插件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题复现

我们都知道在实际的开发中,我们经常遇到需要展示一对多的数据问题,如:一个人共有n个订单,每个订单有不定的商品,那么这种显示的数据结构就是我们的一对多数据结构:如下所示:
在这里插入图片描述
但使用pagehelper分页导致mybatis一对多查询分页结果出错,错误原因在于,一对多collection,他计算的条数是按商品计算的(一对多的“多”,而不是“一”),比如上图中,如果分页参数是pageNum=1,pageSize=2,那么我们想要的结果应该是上图所示,但我们实际查询出来的是,只有orderNo为1的那一部分。

解决办法

1.将原本1条sql的嵌套结果集查询,改为collection的select子查询来实现。
2.自己实现分页插件

### MyBatis 中实现一对多关系查询并带分页功能 #### 使用 `collection` 标签进行一对多查询 为了在 MyBatis 中实现一对多的关系查询,通常可以使用 `<resultMap>` 配合 `<association>` 或者 `<collection>` 来映射复杂的结果集。对于一对多的情况,主要采用 `<collection>` 标签来表示子项集合。 ```xml <resultMap id="ServerWithUsersResultMap" type="com.example.Server"> <id property="id" column="server_id"/> <!-- 其他字段 --> <collection property="users" ofType="com.example.User"> <id property="userId" column="user_id"/> <!-- 用户其他属性 --> </collection> </resultMap> <select id="selectServersWithPaging" resultMap="ServerWithUsersResultMap"> SELECT * FROM server s LEFT JOIN user u ON s.id = u.server_id LIMIT #{offset},#{limit} </select> ``` 上述代码片段定义了一个名为 `ServerWithUsersResultMap` 的结果映射,用于将服务器及其关联用户的记录组合成 Java 对象结构[^1]。 #### 解决分页带来的总数统计问题 当引入分页机制时,可能会遇到一个问题:即返回的数据条目数可能超过预期的总记录数。这是因为默认情况下,MyBatis 可能会对每一条父级记录都执行一次子表的全量查询,从而导致重复计算的问题。为了避免这种情况的发生,在设计 SQL 查询语句时应确保只针对主表应用分页逻辑,并且可以通过额外的一次单独查询获取真实的总记录数目。 一种常见的解决办法是在 XML 映射文件中分别编写两个独立的操作: - **查询列表**:仅对主表施加分页限制; - **查询总数**:不受任何行数限制地统计符合条件的所有记录的数量。 ```sql <!-- 获取分页后的服务端数据 --> <select id="getServersByPage" parameterType="map" resultType="java.util.Map"> SELECT t.*, COUNT(u.user_id) OVER() AS totalElements FROM ( SELECT * FROM server ORDER BY id ASC LIMIT #{pageSize} OFFSET #{startIndex} ) t LEFT JOIN user u ON t.id = u.server_id; </select> <!-- 单独查询总的服务器数量 --> <select id="countAllServers" resultType="int"> SELECT COUNT(*) FROM server WHERE 1=1 ${dynamicConditions}; </select> ``` 这段SQL不仅实现了基于主表的服务端信息分页显示,还利用窗口函数 `COUNT()` 计算了整个结果集中所含有的元素个数,以便前端展示正确的总计数值[^3]。 #### 利用插件简化分页操作 考虑到手写复杂的分页逻辑容易出错以及维护成本较高,推荐借助成熟的第三方库如 PageHelper 插件来进行更高效的分页管理。该工具可以在不影响原有业务逻辑的前提下轻松集成到项目当中,极大地方便开发者快速构建高效稳定的分页方案。 安装依赖后只需简单配置即可生效,具体可参阅官方文档说明[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值