MyBatis Plus 分页插件不生效?别再手写 limit 了!一行配置搞定分页(附避坑指南)
·
大家好,我是“不想打工的码农”。
最近在带几个刚入行的朋友做毕业设计,发现一个极其普遍的问题:
“明明用了 MyBatis Plus,为什么
IPage返回的total是 0?数据能查出来,但总条数和总页数都是错的!”
一问才知道,他们漏掉了最关键的一步——注册分页插件!
今天我就手把手教你怎么用 MyBatis Plus 自带的分页功能,彻底告别手写 limit offset, size 和 count(*) 的原始时代。
一、为什么 MyBatis Plus 分页这么香?
传统分页你需要:
- 写 SQL 查总条数:
SELECT COUNT(*) FROM student WHERE ... - 再写 SQL 查当前页:
SELECT * FROM student WHERE ... LIMIT 10 OFFSET 20 - 手动计算总页数、是否最后一页……
而 MyBatis Plus 只需:
- 调用
selectPage(page, queryWrapper) - 自动返回:当前页数据 + 总记录数 + 总页数 + 当前页码 + 每页大小
前端直接拿去渲染 <el-pagination>,连翻页逻辑都省了大半!
二、正确姿势:3步实现专业分页
第1步:注册分页插件(最容易漏的一步!)
新建配置类 MybatisPlusConfig.java:
@Configuration
@MapperScan("com.yourpackage.mapper") // 替换为你的 mapper 包路径
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件,指定数据库类型
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
✅ 重点:
- 必须使用
MybatisPlusInterceptor(新版 MP 推荐)- 旧版
PaginationInterceptor已废弃!- 这一步只需做一次,全局生效!
第2步:Controller 调用分页方法
@GetMapping("/list")
public IPage<Student> list(
@RequestParam(defaultValue = "1") int current,
@RequestParam(defaultValue = "10") int size,
String name) {
// 1. 构建分页对象
Page<Student> page = new Page<>(current, size);
// 2. 构建查询条件
QueryWrapper<Student> qw = new QueryWrapper<>();
qw.like(StringUtils.isNotBlank(name), "name", name);
// 3. 执行分页查询(核心!)
return studentMapper.selectPage(page, qw);
}
返回的 IPage<Student> 结构如下:
{
"records": [ {...}, {...} ], // 当前页数据
"total": 150, // 总记录数
"size": 10, // 每页大小
"current": 1, // 当前页
"pages": 15 // 总页数
}
第3步:前端对接(以 Vue3 + Element Plus 为例)
<el-table :data="tableData" />
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
@current-change="fetchData"
/>
const fetchData = () => {
axios.get('/student/list', {
params: { current: currentPage.value, size: pageSize.value }
}).then(res => {
tableData.value = res.data.records;
total.value = res.data.total; // ⚠️ 必须取 total,不是 records.length!
});
}
三、避坑指南:分页不生效的3大原因
❌ 坑1:没注册分页插件(最常见!)
如果你跳过第1步,selectPage 会退化成普通查询,只返回第一页数据,total=0。
✅ 解决:检查是否有 MybatisPlusConfig,且 @Bean 方法返回的是 MybatisPlusInterceptor。
❌ 坑2:用了多数据源但没配置插件
如果你用 dynamic-datasource,需要在每个数据源中单独注册插件,或使用全局拦截器。
❌ 坑3:SQL 被手动改写(如 XML 自定义 SQL)
如果在 Mapper XML 中写了 <select id="selectPage">,MP 无法自动注入 COUNT 查询。
✅ 解决:要么用 MP 的 QueryWrapper,要么在 XML 中自己写两条 SQL(不推荐)。
四、性能优化建议
- 给查询字段加索引:分页底层会先执行
COUNT(*),大表无索引会很慢。 - 避免深度分页:
LIMIT 100000, 10性能极差,可改用“游标分页”(基于 ID > lastId)。 - 前端限制最大页码:防止用户恶意请求第 999999 页。
五、结语
MyBatis Plus 的分页功能,是它最实用的特性之一。
但90% 的新手都因为漏掉配置类而放弃使用,转而手写低效代码。
现在你知道了:一行配置,终身受益。
把这篇文章收藏起来,下次分页出问题,直接对照检查!
更多推荐

所有评论(0)