PageHelper 的用法

PageHelper 的用法比手写 LIMIT 简单得多。它的核心思想是"只改一行代码,不碰 SQL":在要分页的查询之前 ,调用 PageHelper.startPage(pageNum, pageSize) 开启分页功能。

下面以最常用的 Spring Boot 项目为例,介绍完整的操作流程。

1. 引入依赖

在你的 pom.xml 文件中,添加 pagehelper-spring-boot-starter 依赖。

xml 复制代码
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.7</version> <!-- 建议使用最新稳定版本 -->
</dependency>

这个 Starter 会自动完成配置,无需额外配置拦截器。

2. 可选配置

在 application.yml 或 application.properties 中,可以做一些个性化配置:

yaml 复制代码
pagehelper:
  helper-dialect: mysql       # 指定数据库类型,Starter会自动识别,但建议明确指定
  reasonable: true            # 分页合理化:pageNum<1查第一页,>总页数查最后一页
  support-methods-arguments: true # 支持通过 Mapper 接口参数传递分页参数

3. 核心用法

这是PageHelper最标准的用法,三步即可:

第一步:在查询前调用 PageHelper.startPage ,设置页码和每页大小。 第二步:执行一个普通的 Mapper 查询 ,不包含任何分页代码。 第三步:用 PageInfo 封装查询结果,获得完整的分页信息。

完整代码示例:

java 复制代码
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public PageInfo<User> findUsersByPage(int pageNum, int pageSize) {
        // 1. 开启分页,只对紧随其后的第一个查询生效
        PageHelper.startPage(pageNum, pageSize);

        // 2. 执行普通查询,PageHelper 会自动拦截并追加 LIMIT
        List<User> userList = userMapper.selectAllUsers();

        // 3. 用 PageInfo 封装结果,它包含了所有分页信息
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        return pageInfo;
    }
}

4. 返回的 PageInfo 对象里有什么?

PageInfo 对象可以直接返回给前端,它包含了前端分页组件需要的所有信息:

属性 说明
total 总记录数
pages 总页数
pageNum 当前页码
pageSize 每页数量
list 当前页的数据列表
hasPreviousPage 是否有上一页
hasNextPage 是否有下一页
isFirstPage / isLastPage 是否为第一/最后一页

5. ⚠️ 重要注意事项

原理说明

PageHelper 本质上是利用 MyBatis 的拦截器机制,在执行查询前,额外执行一次 SELECT COUNT(*) 来获取总记录数,并在原 SQL 后追加 LIMIT 子句。

核心原则

  1. 紧挨查询 :PageHelper.startPage() 必须紧挨着它要分页的那个 Mapper 查询方法,中间不能有其他数据库查询操作。
  2. 只对第一个查询生效 :它只会影响紧随其后的第一个 SELECT 查询。
  3. 不支持 for update :分页插件不支持带有 for update 的 SQL。

使用陷阱

  1. ThreadLocal 污染 :如果在一个线程中调用了 PageHelper.startPage(),但后续没有执行查询,分页参数会一直残留,可能意外影响其他查询。解决方法 :可以在每次分页后调用 PageHelper.clearPage() 手动清理上下文。
  2. 勿重复分页 :如果 Mapper 的 SQL 里已经写了 LIMIT,PageHelper 会再次添加,导致 SQL 语法错误或结果异常。
  3. 复杂关联查询 :在复杂的多表关联查询中,如果存在 1:N 关系,PageHelper 自动生成的 COUNT 语句可能不准确。

6. 进阶用法

分页的同时进行排序

java 复制代码
PageHelper.startPage(1, 10).orderBy("id desc");
// 或
PageHelper.startPage(1, 10, "id desc");

手动控制 COUNT 查询

java 复制代码
// 禁用总记录数查询,用于不需要 total 的场景,可提升性能
PageHelper.startPage(1, 10, false);

// 使用 Lambda 表达式进行分页,可自定义 COUNT 逻辑
PageInfo<User> pageInfo = PageHelper.startPage(1, 10)
    .doSelectPageInfo(() -> userMapper.selectUsersWithComplexJoin());

总结

总的来说,引入依赖 → 调用 startPage → 执行查询 → 封装 PageInfo 这四步就是 PageHelper 最核心的使用流程。它把分页逻辑从 SQL 中抽离出来,让代码更干净,也更容易维护。

相关推荐
明月_清风16 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端
leikooo16 小时前
用餐厅和盘子理解栈和堆
java·数据结构·链表·rust
Ivanqhz17 小时前
激活函数在 Transformer 中的作用及各种变体简述
java·linux·数据库·人工智能·深度学习
沙漠之主18 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
FPGA小徐18 小时前
PA1 基础设施(2)深度解析:NEMU 中 ITRACE、MTRACE、FTRACE、IRINGBUF、ETRACE、DIFFTEST 全解析
java·服务器·网络
YOLO数据集集合18 小时前
EvoAgent:面向PR研发治理的自进化Multi-Agent Harness系统
java·开发语言·目标检测·agent·自进化
hsfxuebao18 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
知行EDI18 小时前
知行之桥 MaBang 端口使用指南——Create Order 订单创建篇
java·服务器·数据库
笑鸿的学习笔记18 小时前
C++笔记之大块顺序写
java·c++·笔记
打工仔折腾 AI19 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战