PageHelper.startPage(1, 10) 能编译,不代表 MyBatis 真正使用了分页插件。查询返回全部数据时,要同时检查插件是否接入目标会话工厂,以及分页调用是否作用在目标查询上。
当时的区别在依赖接入方式
2019 年在一个 Spring Boot 工程中调用 startPage,仍得到全部结果。同样写法在另一个工程正常,于是对照 POM:新工程只引用 PageHelper 核心库,旧工程使用 pagehelper-spring-boot-starter。换成 Starter 后,当时分页恢复。
这说明“类在 classpath 中”和“插件已参与 SQL 执行”是两回事,不说明核心库不能分页。Starter 提供框架整合;手动接入核心库也可以,但必须配置正确。
先确认插件属于哪一个 SqlSessionFactory
PageHelper 使用文档 说明了依赖与拦截器配置。以使用 PageInterceptor 的版本为例,MyBatis XML 的核心片段是:
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
它应放在实际生效的 MyBatis 配置中的合法位置;使用 Spring 或多个数据源时,要确认目标 Mapper 对应的 SqlSessionFactory 安装了插件,而不是另一个工厂有插件就算接入成功。
采用 Spring Boot Starter 时,按实际 Boot、MyBatis 和 Starter 版本核查自动配置,避免重复手工注册。不把某个今天的 Starter 版本直接塞进旧工程。
startPage 紧邻真正要分页的查询
PageHelper 的同步调用使用线程上下文,紧随 startPage 的查询应是目标查询,而不是插入一个额外的数据库操作:
try {
PageHelper.startPage(pageNum, pageSize);
List<Book> rows = bookMapper.selectAll();
PageInfo<Book> page = new PageInfo<>(rows);
return page;
} finally {
PageHelper.clearPage();
}
这是服务方法中的结构片段,Book、Mapper 和返回类型由项目提供。先做参数校验,再设置分页;不要设置后可能直接返回,或切换线程才执行查询。finally 清理也便于覆盖查询前异常等路径。
验证分页,而不只是验证集合长度
在受控测试库检查实际生成的分页 SQL、查询数据源、排序和返回页信息。测试数据少于十条时,返回十条以内无法证明分页生效;应使用足够记录,并比较第一页、第二页和总数。
页码、页大小的限制与 reasonable、pageSizeZero 等行为也要按配置确认。核心库换成 Starter 可以解决接入遗漏,但不会自动修正错误的调用位置、错误工厂或不稳定排序。