编辑
2025-06-04
Java
00
请注意,本文编写于 185 天前,最后修改于 46 天前,其中某些信息可能已经过时。

目录

一、快速入门
二、实用技巧
三、避坑指南
四、最佳实践

在MyBatis项目中,手动写LIMIT语句进行分页不仅繁琐,而且难以维护。PageHelper通过一句代码就能实现物理分页,极大提升开发效率。

一、快速入门

1. 引入依赖

xml
<!-- Spring Boot --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>最新版本</version> </dependency>

2. 基础使用(核心用法) 在查询方法前调用PageHelper.startPage即可。

java
@Service public class UserService { @Autowired private UserMapper userMapper; public PageInfo<User> getUsers(int pageNum, int pageSize) { // 只有紧跟在后的第一个MyBatis查询方法会被分页 PageHelper.startPage(pageNum, pageSize); List<User> userList = userMapper.selectAll(); return new PageInfo<>(userList); } }

3. 返回结果 PageInfo对象包含完整的分页信息:

json
{ "pageNum": 1, "pageSize": 10, "total": 100, "list": [...], // 当前页数据 "hasNextPage": true, "pages": 10 // 总页数 }

二、实用技巧

1. 更简洁的写法(推荐) 使用PageMethod的静态方法,代码更清晰:

java
PageInfo<User> pageInfo = PageMethod.startPage(pageNum, pageSize) .doSelectPageInfo(() -> userMapper.selectByCondition(condition));

2. 排序支持

java
// 单字段排序 PageHelper.startPage(pageNum, pageSize, "create_time DESC"); // 多字段排序 String orderBy = "name ASC, id DESC"; PageHelper.startPage(pageNum, pageSize, orderBy);

3. 只获取总数不查数据

java
Page<?> page = PageHelper.startPage(pageNum, pageSize, true); userMapper.selectComplexQuery(params); long total = page.getTotal(); // 获取总数,list为空

4. 参数安全处理

java
// 设置分页参数合理范围 public PageInfo<User> safeQuery(int pageNum, int pageSize) { pageNum = Math.max(1, pageNum); // 至少第一页 pageSize = Math.min(100, Math.max(1, pageSize)); // 限制1-100条 return PageMethod.startPage(pageNum, pageSize) .doSelectPageInfo(() -> userMapper.selectAll()); }

三、避坑指南

1. 线程安全问题

  • PageHelper基于ThreadLocal,确保在** finally 块**中清理,或使用PageMethod的lambda写法自动清理

2. 分页失效的常见原因

  • 没有紧跟在查询方法前调用
  • 在代码执行路径中出现了多次startPage
  • 配置了defaultCount=false且没有手动指定count查询

3. 一对多查询的分页问题resultMap中使用collection会导致分页总数不准,解决方案:

  • 使用子查询代替collection
  • 先分页查询主表,再批量查询关联数据

4. 自定义Count查询 对于复杂查询,可以指定专用的count语句:

java
@Select({"<script>", "SELECT * FROM user WHERE 1=1", "<when test='name!=null'> AND name like #{name}</when>", "</script>"}) List<User> selectComplex(UserQuery query); // 对应的count查询 @Select({"<script>", "SELECT COUNT(1) FROM user WHERE 1=1", "<when test='name!=null'> AND name like #{name}</when>", "</script>"}) Long countComplex(UserQuery query);

四、最佳实践

  1. 统一分页响应:封装统一的PageResult类,避免直接返回PageInfo
  2. 配置合理化:在yml中设置reasonable=true,页码超出范围时自动修正
  3. 性能优化:复杂count查询考虑缓存或估算总数

配置示例:

yaml
pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true

总结:PageHelper用最简单的API解决了最繁琐的分页问题,掌握这些技巧能让你的分页代码更加健壮和高效。

本文作者:zjx171

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!