文章目录
🧾 什么是 PageHelper?
PageHelper 是 MyBatis 的一个分页插件,可以自动在 SQL 后面加上 limit 语句,帮助我们实现分页效果。
你只要写一个普通的查询语句,它会自动帮你加上分页语句,比如:
PageHelper.startPage(1, 10);
List<User> users = userMapper.selectAll();
PageHelper 会帮你把 SQL 变成这样:
SELECT * FROM user LIMIT 0, 10;
🧠 它的底层是怎么做到的?
PageHelper 的核心原理是:MyBatis 插件机制(拦截器 Interceptor)+ ThreadLocal + SQL 改写
核心步骤有 4 个:
✅ 1. 利用 MyBatis 的插件机制
MyBatis 允许开发者写拦截器拦截 SQL 执行过程,比如:
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {...})
})
PageHelper 就写了一个拦截器,拦截的是 Executor.query(…) 方法。
✅ 2. 用 ThreadLocal 暂存分页信息
当你调用:
PageHelper.startPage(1, 10);
PageHelper 就会把这个分页参数(页码、每页条数)存到 ThreadLocal 中,方便后面使用。
ThreadLocal 是一个线程本地变量,不会影响其他线程。
✅ 3. 拦截查询语句并修改 SQL
拦截器在查询语句执行前拿到了原始 SQL,然后从 ThreadLocal 里取出分页参数,把 SQL 改成带 LIMIT
的样子:
比如:
SELECT * FROM user
变成:
SELECT * FROM user LIMIT 0, 10
注意:它不是直接改你写的 SQL,而是改 MyBatis 构造好的 SQL,再交给数据库执行。
✅ 4. 执行分页查询并封装 Page 对象
执行完 SQL 后,PageHelper 还会生成一个 Page<T>
对象,里面包含:
- 当前页数据
- 总记录数(通过 count 查询)
- 总页数
- 当前页码等信息
方便你在前端展示。
🎯 总结一下
步骤 | 做了什么 |
---|---|
1 | 拦截 MyBatis 执行 SQL 的过程 |
2 | 用 ThreadLocal 保存分页参数 |
3 | 修改 SQL,加上 LIMIT 子句 |
4 | 执行 SQL,封装分页结果为 Page 对象 |