← 每日面试题 学习看板

MyBatis-Plus的分页原理是什么?

面试题/00java/04 框架/03Mybatis/MyBatis-Plus的分页原理是什么?.md

面试记录 2026-10-27(Round 29)

题目: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 次作答

L1 · 30 秒速记

结论:MyBatis-Plus 分页本质是拦截 SQL、改写分页,走 MyBatis 拦截器插件机制,物理分页。 关键词:Interceptor 拦截 · LIMIT 改写 · count 优化 边界:深分页(offset 极大)LIMIT 也慢,需游标/索引。

L2 · 核心讲解

核心考点定位:考察是否理解 MyBatis 插件机制(不是 AOP),以及分页是物理还是内存。面试官想排除"分页 = 内存分页"和"分页 = AOP"两个错误认知。

机制链(≥3 环):

  1. 查询执行 → MybatisPlusInterceptor 拦截 Executor.query:为什么——MyBatis 插件基于 JDK 动态代理拦截 Executor,这是 MP 挂载点
  2. 拦截到 Page 参数 → 先查 count:为什么——分页需要总数,count 可智能改写优化
  3. count 完成 → 改写 SQL 加 LIMIT:为什么——物理分页,数据库层只回当前页数据

证据锚点(≥6):

对比与权衡:

方案正确性成本失败模式适用边界
MP 物理分页高低(SQL 改写)深分页慢常规列表分页
PageHelper 内存分页中高(全量查回)数据量大 OOM小表/已全量场景
游标分页高中不支持跳页大表深分页

常见误区:

  1. 错误:MP 分页是 AOP → 正确:是 MyBatis Interceptor 插件(JDK 动态代理拦截 Executor)→ 为什么:AOP 切的是 Spring Bean,MyBatis 插件切的是 Executor,机制不同
  2. 错误:MP 分页是内存分页 → 正确:物理分页,改写 SQL 加 LIMIT → 为什么:内存分页全量查回,大数据灾难
  3. 错误:count 查询每次全表 → 正确:MP 智能改写 count 优化 → 为什么:能改写成 COUNT(*) 就改写,减少扫描

适用边界:MP 分页只对"能改写 SQL 的查询"有效;自定义复杂 SQL(多表 join)count 可能不准,需指定 count 列;深分页 LIMIT 也慢,改游标。

延伸追问(≥3)

  1. 为什么 count 要单独查?
  1. 大表深分页 limit 1000000,10 为什么慢?
  1. 多表 join 分页要注意什么?

面试者参考回答(400–700 字)

【结论】 面试官您好,MyBatis-Plus 分页本质是拦截 SQL、改写分页,走的是 MyBatis 的拦截器插件机制,属于物理分页。

【三点】 第一,MyBatis 插件基于 JDK 动态代理拦截 Executor 的方法,MP 用 MybatisPlusInterceptor 注册 PaginationInnerInterceptor,这就是挂载点,不是 AOP。第二,分页做两件事——先 count 总数(能优化成 COUNT(*) 就优化),再改写原 SQL 加 LIMIT,只查当前页数据,这是物理分页。第三,相比 PageHelper 的内存分页(全量查回再 subList),MP 高效得多,大数据量下内存分页会 OOM。

【边界】 当然,深分页(offset 极大)即使 LIMIT 也慢,因为数据库要扫描大量行再丢弃,那时得用游标或索引定位,别指望分页插件解决一切。


作答历史

#日期评分本轮主要问题记录
12026-10-273/5机制名称不准(AOP vs Interceptor),漏 count 优化第 1 次