1. 问题现象:当MyBatis-Plus遇上PageHelper
最近在Spring Boot项目中同时使用MyBatis-Plus和PageHelper时,发现一个诡异现象:配置了MyBatis-Plus的分页插件后,执行分页查询时返回的却是全部数据。经过排查发现,当项目中同时存在PageHelper依赖时,MyBatis-Plus的分页功能就会失效,这种现象被开发者们戏称为"假分页"。
这种情况在实际开发中并不少见,特别是老项目迁移到MyBatis-Plus时,原有的PageHelper代码可能还保留着。两个分页插件在底层实现机制上存在冲突,导致分页功能异常。下面我们就来深入分析这个问题的根源。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 源码解析:冲突的底层机制
2.1 MyBatis-Plus分页原理
MyBatis-Plus的分页插件(PaginationInnerInterceptor)是通过拦截器机制实现的。当执行查询方法时,拦截器会检测是否需要分页:
java复制public class PaginationInnerInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms,
Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql) {
// 判断是否需要分页
if (parameter instanceof Map) {
Map<?, ?> parameterMap = (Map<?, ?>) parameter;
IPage<?> page = (IPage<?>) parameterMap.get("page");
if (page != null) {
// 执行分页逻辑
handlePage(ms, boundSql, page);
}
}
}
}
关键点在于,MyBatis-Plus的分页是通过在SQL执行前修改BoundSql对象,添加LIMIT语句实现的。
2.2 PageHelper工作原理
PageHelper同样是通过拦截器实现分页,但它采用的是ThreadLocal方式:
java复制public class PageHelper implements Interceptor {
private static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<>();
public static <E> Page<E> startPage(int pageNum, int page
