PageHelper是 MyBatis 框架下应用最广泛的分页插件,能让你免去手写LIMIT等分页语句的繁琐工作。它通过拦截 SQL 并自动为其添加分页语法(如 MySQL 的LIMIT)来工作。
💡 为什么需要 PageHelper?
当数据量大时,一次性查询所有数据会导致性能问题。PageHelper的价值在于:
简化开发:无需手动拼接分页 SQL,只需调用
startPage方法即可。减少错误:自动处理不同数据库的分页方言,避免了手写 SQL 可能出现的错误。
功能全面:能自动查询总记录数,并提供了
PageInfo类来封装总页数、导航页码等丰富信息。
⚙️ 工作原理
PageHelper的核心机制如下:
存储参数:调用
PageHelper.startPage(pageNum, pageSize)时,分页参数被存入当前线程的ThreadLocal变量中。拦截 SQL:MyBatis 执行查询时,
PageHelper的拦截器会拦截该 SQL。改写 SQL:拦截器从
ThreadLocal取出分页参数,并根据数据库方言,在原始 SQL 后动态添加分页语句(如LIMIT)。执行 COUNT:自动执行
SELECT COUNT(*)获取总记录数。清理上下文:分页完成后,自动清除
ThreadLocal中的参数,避免线程池复用带来干扰。
🚀 快速上手
1. 添加依赖
对于 Spring Boot 项目,推荐使用pagehelper-spring-boot-starter。
xml
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.7</version> <!-- 建议使用最新稳定版 --> </dependency>
2. 配置(可选)
在 Spring Boot 的application.yml文件中进行配置。
yaml
pagehelper: helper-dialect: mysql # 指定数据库方言,可自动识别[reference:21] reasonable: true # 分页合理化,如页码超出范围时自动修正[reference:22] support-methods-arguments: true # 支持通过 Mapper 方法参数传递分页参数[reference:23]
3. 核心代码
标准的编码模式是:设置分页 -> 执行查询 -> 封装结果。
java
// 1. 设置分页参数 PageHelper.startPage(pageNum, pageSize); // 2. 执行查询(此查询会被自动分页) List<User> userList = userMapper.selectAllUsers(); // 3. 使用 PageInfo 封装结果,获取分页信息 PageInfo<User> pageInfo = new PageInfo<>(userList);
其中,PageInfo对象包含了total(总记录数)、pages(总页数)、pageNum(当前页码) 等非常详细的属性。
⚠️ 常见问题与避坑指南
startPage无效:确保PageHelper.startPage()调用后紧跟的是第一个MyBatis 查询方法。两者之间不要有其他无关的查询或代码。分页上下文未清理:在同一个线程中连续分页,可能相互干扰。建议在每次分页操作后,调用
PageHelper.clearPage()手动清理。PageHelper与MyBatis-Plus冲突:MyBatis-Plus自带分页插件,两者同时使用会冲突。如果项目使用了MyBatis-Plus,应使用其内置的分页功能,并移除PageHelper依赖。COUNT 查询性能问题:对于复杂 SQL,自动生成的
COUNT查询可能很慢。可通过配置count=countSql参数进行优化。版本与配置问题:若从 4.x 升级到 5.x,拦截器类名已变,需确保配置正确。非 Spring Boot 项目需在 MyBatis 配置文件 (
mybatis-config.xml) 中正确配置PageInterceptor。特殊 SQL 问题:
PageHelper不支持包含FOR UPDATE的 SQL,对于此类 SQL 建议自行手动处理分页。
💎 总结
PageHelper是简化 MyBatis 分页操作的利器。它的核心用法就是三步:startPage-> 执行查询 ->PageInfo封装。使用时,关键是要注意startPage必须紧跟查询,并留意线程上下文和版本配置的细节。对于更特殊或复杂的场景,可以查阅其 官方文档 以获得更深入的信息。