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 可以解决接入遗漏,但不会自动修正错误的调用位置、错误工厂或不稳定排序。