pagehelper通过拦截executor在数据库层面实现物理分页,自动重写sql并注入分页参数;需引入pagehelper-spring-boot-starter依赖,配置helper-dialect等参数,调用pagehelper.startpage()后紧跟mapper查询即可返回pageinfo封装结果。

在 MyBatis 中使用 PageHelper 实现物理分页,核心是让 SQL 在数据库层面完成 LIMIT/OFFSET(MySQL)、ROWNUM(Oracle)或 FETCH OFFSET(PostgreSQL)等操作,而不是在 Java 内存中做 list.subList()。PageHelper 通过拦截 Executor,自动重写 SQL 并注入分页参数,对业务代码侵入极小。
引入依赖
确保项目中已添加 PageHelper 的 starter(推荐用官方维护的 mybatis-plus 不是必须,但 PageHelper 官方推荐搭配 MyBatis 原生使用):
Maven 依赖(以最新稳定版 5.3.3 为例):
<dependency><groupid>com.github.pagehelper</groupid><artifactid>pagehelper-spring-boot-starter</artifactid><version>1.4.7</version><!-- 注意:该 starter 已适配 Spring Boot 2.x/3.x,内部含 pagehelper 5.3.x --></dependency>
若未用 Spring Boot,可直接引入 pagehelper + 手动配置插件。
配置分页插件(Spring Boot 方式)
在 application.yml 中启用并指定数据库方言:
pagehelper:
helper-dialect: mysql # 必填,根据实际数据库选:mysql / oracle / postgresql / sqlserver 等
reasonable: true # 启用合理化分页(页码≤0时转为1,超出最大页时转为最后一页)
support-methods-arguments: true # 允许在 Mapper 方法中用 @Param("pageNum")、@Param("pageSize") 传参
params: count=countSql # 默认开启 count 查询(用于计算总条数),不建议关闭
无需额外 Java 配置类,starter 会自动注册 PageInterceptor 到 SqlSessionFactory。
在 Service 中调用分页查询
关键:在执行查询前,**紧挨着**调用 PageHelper.startPage(),之后紧跟一次普通 Mapper 查询方法即可,PageHelper 会自动拦截并改写 SQL:
- 方式一:使用静态方法(最常用)
public PageInfo<user> listUsers(int pageNum, int pageSize) {
// 开启分页(必须在查询前调用,且只对紧接的下一次查询生效)
PageHelper.startPage(pageNum, pageSize);
<pre class="brush:java;toolbar:false;">// 执行原始查询(Mapper 返回 List,PageHelper 会包装成 PageInfo)
List<User> users = userMapper.selectAll();
// 封装分页信息(含 total、list、pageNum、pageSize、pages 等)
return new PageInfo<>(users);
}
- 方式二:支持方法参数传参(需配置 support-methods-arguments: true)
// Mapper 接口方法
List<user> selectByStatus(@Param("status") Integer status,
@Param("pageNum") Integer pageNum,
@Param("pageSize") Integer pageSize);
<p>// 调用时直接传页码和大小,PageHelper 自动识别
PageHelper.startPage(2, 10);
List<user> list = mapper.selectByStatus(1, 2, 10); // 注意:pageNum/pageSize 参数值要与 startPage 一致,否则行为不确定</user></p></user>
注意:PageHelper 的分页只对紧随其后的第一个查询生效;多次查询需重复 startPage;不建议在循环中反复 startPage + 查询,应合并为一次分页查询。
理解 PageInfo 和底层行为
PageInfo 是 PageHelper 提供的分页结果封装类,包含:
-
total:总记录数(由 PageHelper 自动执行的 COUNT 查询得出) -
list:当前页数据列表(已应用 LIMIT) -
pageNum、pageSize、pages(总页数)、isFirstPage、isLastPage等便捷属性
SQL 执行过程实际是两步:
① 自动生成并执行 SELECT COUNT(*) FROM ... WHERE ...(可关闭,但失去 total)
② 改写原 SQL 为带 LIMIT 的物理分页语句,例如 MySQL 下变为:SELECT * FROM user WHERE status = 1 LIMIT 10,10
不复杂但容易忽略:确保数据库连接 URL 中没有 useSSL=false&serverTimezone=UTC 类参数缺失(尤其 MySQL 8+),否则可能因时区或 SSL 导致 COUNT 查询失败,进而分页异常。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











