news 2026/2/13 15:39:46

MyBatis-Plus 分页插件失效?深扒 PageHelper 与 MP 冲突的底层源码,教你避开“假分页”陷阱

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyBatis-Plus 分页插件失效?深扒 PageHelper 与 MP 冲突的底层源码,教你避开“假分页”陷阱

🚨 前言:凌晨 1 点的 OOM 惊魂

场景还原:生产环境某个列表接口突然响应巨慢,紧接着应用抛出OOM (Out Of Memory)崩溃。
排查日志发现,原本应该是分页查询的 SQL,竟然没有LIMIT语句!

-- 期望的 SQL (物理分页)SELECT*FROMuserWHEREstatus=1LIMIT0,10-- 实际执行的 SQL (全表扫描 + 内存分页)SELECT*FROMuserWHEREstatus=1

这就是典型的分页插件失效。如果表里有 100 万行数据,应用服务器的内存瞬间就会被撑爆。


⚔️ 一、 核心原理:MyBatis 的拦截器机制

要理解为什么失效,必须先懂 MyBatis 的插件原理。
MyBatis 允许我们在 SQL 执行的生命周期中进行拦截(Interceptor)。

  • PageHelper:通过PageInterceptor拦截Executor,检测ThreadLocal中是否有Page对象(PageHelper.startPage()),如果有,就改写 SQL。
  • MyBatis-Plus:通过MybatisPlusInterceptor拦截Executor,检测参数中是否有IPage接口的实现类,如果有,就改写 SQL 添加LIMIT

拦截器链示意图 (Mermaid):

1. Mapper 调用

执行最终 SQL

拦截器链 (责任链模式)

放行

放行

改写 SQL (LIMIT)

拦截器 A

拦截器 B

MP 分页拦截器

PageHelper 拦截器

应用代码

MyBatis 核心

数据库


💣 二、 事故现场:三种常见的“失效”姿势

1. 最低级错误:完全没配置拦截器 (MP 3.4.0+)

很多新手以为引入了mybatis-plus-boot-starter就万事大吉了。
错!在 MP 3.4.0 之后,必须显式配置MybatisPlusInterceptorBean,否则分页功能完全不生效。

错误代码:

// ControllerPage<User>page=newPage<>(1,10);userMapper.selectPage(page,null);// 结果:SQL 无 LIMIT,全表查询
2. 隐形冲突:PageHelper 抢戏

如果你的项目里既引入了pagehelper-spring-boot-starter,又想用 MP 的selectPage
PageHelper 的自动配置可能会干扰 MP,或者在同一个 ThreadLocal 里产生了脏数据。
虽然现在的版本兼容性好了很多,但混用依然是 Bug 的温床。

3. 参数传递错误

如果你在自定义 SQL 中使用分页:

// MapperList<User>selectUserList(Page<User>page,@Param("name")Stringname);

如果Page对象不是第一个参数,且没有正确处理,MP 的拦截器可能识别不到它,从而放弃改写 SQL。


🔍 三、 源码深扒:为什么配置了 Bean 还是没用?

假设你已经配置了MybatisPlusInterceptor,但依然失效。我们需要看源码。

打开MybatisPlusInterceptor.java,找到intercept方法:

@OverridepublicObjectintercept(Invocationinvocation)throwsThrowable{// 1. 获取所有内部拦截器 (如分页、乐观锁等)List<InnerInterceptor>interceptors=this.interceptors;// 2. 遍历拦截器for(InnerInterceptorinterceptor:interceptors){// 3. 调用 willDoQuery (关键点!)// 这里会判断是否需要进行分页处理if(!interceptor.willDoQuery(executor,ms,parameter,rowBounds,resultHandler,boundSql)){returninterceptor.beforeQuery(executor,ms,parameter,rowBounds,resultHandler,boundSql);}}// ...}

再看PaginationInnerInterceptor.java(分页拦截器核心):

@OverridepublicbooleanwillDoQuery(...){// 1. 获取参数中的 IPage 对象IPage<?>page=ParameterUtils.findPage(parameter).orElse(null);// 2. 如果参数里没找到 Page 对象,或者 Page.size < 0if(page==null||page.getSize()<0||!page.isSearchCount()){// 直接返回 true,不做处理 -> 导致 LIMIT 缺失!returntrue;}// ...}

结论:只要 MP 在参数列表里找不到IPage对象,它就当作普通查询处理,直接放行,导致“假分页”。


✅ 四、 终极解决方案

方案 1:标准配置 (必做)

在 Spring Boot 配置类中,必须注册MybatisPlusInterceptor,并添加PaginationInnerInterceptor

@ConfigurationpublicclassMybatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();// 1. 添加分页拦截器// DbType.MYSQL 根据你的数据库类型选择,不要漏了!interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));// (可选) 如果有乐观锁等其他插件,也在这里添加// interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());returninterceptor;}}
方案 2:依赖隔离 (推荐)

如果新项目全面拥抱 MP,建议直接移除 PageHelper 依赖

方案 3:自定义 SQL 的规范写法

在 Mapper.xml 对应的 Interface 中,确保Page参数放在第一位,或者虽然不在第一位但 MP 能识别。

// ✅ 推荐写法:Page 放在第一个参数IPage<UserDto>selectCustomUsers(IPage<UserDto>page,@Param("status")Integerstatus);

📊 五、 性能自测:怎么确认分页生效了?

不要只看接口返回的数据条数!

  1. 开启 MP 的 SQL 打印
mybatis-plus:configuration:log-impl:org.apache.ibatis.logging.stdout.StdOutImpl
  1. 观察控制台
  • 正常:看到LIMIT ?, ?结尾的 SQL。
  • 异常:看到SELECT count(0)...查总数,但随后的查询语句没有LIMIT

🎯 总结

MyBatis-Plus 的分页插件失效,90% 都是因为配置缺失依赖冲突
“假分页”是生产环境的隐形杀手,它平时不报错,一到大促流量洪峰就 OOM。

Next Step:
赶紧去检查一下你的 Config 类,那个new MybatisPlusInterceptor()到底加了没?别等到报警电话响了才后悔!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 14:43:44

临终关怀应用:病人最爱的人声由VoxCPM-1.5-TTS-WEB-UI永久保存

临终关怀中的声音传承&#xff1a;用AI永久保存至亲之音 在重症监护室的灯光下&#xff0c;一位老人轻声对孩子说“别怕&#xff0c;爸爸一直都在”。这句温柔的话语&#xff0c;或许将成为他最后的遗言。但今天&#xff0c;这句话不再只是记忆中模糊的回响——借助人工智能&am…

作者头像 李华
网站建设 2026/2/11 8:56:23

电商运营(浅数据看销量,大数据看趋势,深数据挖需求)

在数字化电商竞争的深水区&#xff0c;数据已从“辅助工具”升级为“核心竞争力”。多数运营者困于“只见销量波动&#xff0c;不见增长本质”&#xff0c;核心问题在于对数据的挖掘深度不足。真正高效的电商运营&#xff0c;需建立“浅-大-深”三层数据思维&#xff1a;浅数据…

作者头像 李华
网站建设 2026/2/10 14:46:57

导师严选10个AI论文写作软件,助本科生轻松搞定毕业论文!

导师严选10个AI论文写作软件&#xff0c;助本科生轻松搞定毕业论文&#xff01; AI工具如何成为论文写作的得力助手 随着人工智能技术的不断进步&#xff0c;越来越多的AI工具被引入到学术写作领域&#xff0c;为本科生提供高效、便捷的支持。尤其是在论文写作过程中&#xff0…

作者头像 李华
网站建设 2026/2/7 22:35:19

CSDN官网夜间模式适配长时间阅读VoxCPM-1.5-TTS文档

VoxCPM-1.5-TTS&#xff1a;让技术文档“开口说话”的夜间阅读新体验 在程序员的日常中&#xff0c;通宵阅读 CSDN 上一篇万字长文、反复研读某框架源码解析或啃下一份晦涩的技术白皮书&#xff0c;并不罕见。然而&#xff0c;长时间盯着屏幕带来的视觉疲劳&#xff0c;往往让人…

作者头像 李华
网站建设 2026/2/8 19:28:41

MIT License版本Sonic允许自由修改与商用

MIT License版本Sonic允许自由修改与商用 在短视频、直播电商和在线教育高速发展的今天&#xff0c;虚拟内容的生产效率正面临前所未有的挑战。如何以更低的成本、更快的速度生成高质量的数字人视频&#xff1f;传统方案依赖3D建模与动作捕捉&#xff0c;不仅流程繁琐&#xff…

作者头像 李华
网站建设 2026/2/12 4:16:54

uniapp+ssm医院预约挂号小程序

目录摘要项目技术支持论文大纲核心代码部分展示可定制开发之亮点部门介绍结论源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作摘要 医院预约挂号小程序基于Uniapp和SSM框架开发&#xff0c;旨在优化传统挂号流程&#xff0c;提升患者就医效…

作者头像 李华