题目:MyBatis-Plus 的分页原理是什么?
难度:difficulty/low
评分:⭐⭐⭐☆☆(3/5)
MyBatis-Plus 的分页插件原理本质是动态 SQL 的织入,基于 AOP 拦截 SQL 执行,将分页相关的内容织入到执行的 SQL 中,来实现分页功能。
优点:核心方向对——拦截 SQL 并织入分页。
不足:机制名称不准——是 MyBatis Interceptor 插件机制,不是 AOP;漏 PaginationInnerInterceptor、count 优化、物理 vs 内存分页。
补充:MP 分页是物理分页(改写 SQL 加 LIMIT);MyBatis 的 PageHelper 有物理/内存之分。
最后更新:2026-10-27 · 基于第 1 次作答
结论:MyBatis-Plus 分页本质是拦截 SQL、改写分页,走 MyBatis 拦截器插件机制,物理分页。 关键词:Interceptor 拦截 · LIMIT 改写 · count 优化 边界:深分页(offset 极大)LIMIT 也慢,需游标/索引。
核心考点定位:考察是否理解 MyBatis 插件机制(不是 AOP),以及分页是物理还是内存。面试官想排除"分页 = 内存分页"和"分页 = AOP"两个错误认知。
机制链(≥3 环):
MybatisPlusInterceptor 拦截 Executor.query:为什么——MyBatis 插件基于 JDK 动态代理拦截 Executor,这是 MP 挂载点证据锚点(≥6):
MybatisPlusInterceptor:MP 提供的全局拦截器PaginationInnerInterceptor:分页核心拦截器,注册进 MybatisPlusInterceptorExecutor.query:MyBatis 执行器方法,被代理拦截LIMIT offset,size:改写后 SQL,物理分页关键COUNT(*):count 查询智能改写目标Page<T>:分页参数对象,携带 current/size对比与权衡:
| 方案 | 正确性 | 成本 | 失败模式 | 适用边界 |
|---|---|---|---|---|
| MP 物理分页 | 高 | 低(SQL 改写) | 深分页慢 | 常规列表分页 |
| PageHelper 内存分页 | 中 | 高(全量查回) | 数据量大 OOM | 小表/已全量场景 |
| 游标分页 | 高 | 中 | 不支持跳页 | 大表深分页 |
常见误区:
适用边界:MP 分页只对"能改写 SQL 的查询"有效;自定义复杂 SQL(多表 join)count 可能不准,需指定 count 列;深分页 LIMIT 也慢,改游标。
【结论】 面试官您好,MyBatis-Plus 分页本质是拦截 SQL、改写分页,走的是 MyBatis 的拦截器插件机制,属于物理分页。
【三点】 第一,MyBatis 插件基于 JDK 动态代理拦截 Executor 的方法,MP 用 MybatisPlusInterceptor 注册 PaginationInnerInterceptor,这就是挂载点,不是 AOP。第二,分页做两件事——先 count 总数(能优化成 COUNT(*) 就优化),再改写原 SQL 加 LIMIT,只查当前页数据,这是物理分页。第三,相比 PageHelper 的内存分页(全量查回再 subList),MP 高效得多,大数据量下内存分页会 OOM。
【边界】 当然,深分页(offset 极大)即使 LIMIT 也慢,因为数据库要扫描大量行再丢弃,那时得用游标或索引定位,别指望分页插件解决一切。
| # | 日期 | 评分 | 本轮主要问题 | 记录 |
|---|---|---|---|---|
| 1 | 2026-10-27 | 3/5 | 机制名称不准(AOP vs Interceptor),漏 count 优化 | 第 1 次 |