MyBatis-Plus 分页查询两种实现方案
一、方案一:PageUtils 工具类分页(ThreadLocal 封装版)
1. 方案概述
PageUtils.startPage()是项目统一封装的分页工具类,基于 MyBatis-Plus 分页插件实现,通过 ThreadLocal 存储分页参数,对业务代码无侵入,是传统项目 / 老项目最常用的分页方式。
2. 核心原理
- 调用
startPage()后,工具类自动获取前端传递的页码、每页条数; - MyBatis-Plus 分页插件拦截 SQL,自动拼接
LIMIT分页语法; - 执行查询返回
List集合,工具类自动封装成分页结果集。
3. 适用场景
- 项目已统一封装分页工具类
- 不希望修改 Mapper/Service 层原有代码
- 快速实现分页,低成本改造
4. 完整代码示例
4.1 Controller 层
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; /** * 案件维度管理 Controller */ @RestController @RequestMapping("/justice/case/dimension") public class JusticeCaseDimensionController { @Resource private CaseDimensionContext caseDimensionContext; /** * 按范围查询案件聚合维度(账龄+批次号/被告) * 方案一:PageUtils 工具类分页 */ @GetMapping("/selectCaseDimensionByScope") public R<JusticeCaseDimension> selectCaseDimensionByScope(JusticeCaseDimensionQuery caseDimensionQuery) { // 1. 开启分页(核心:自动接收前端 page/pageSize 参数) PageUtils.startPage(); // 2. 执行业务查询,返回普通 List 集合 List<JusticeCaseDimension> justiceCaseDimensions = caseDimensionContext.selectCaseDimensionByScope(caseDimensionQuery); // 3. 工具类封装 List 为分页结果返回 return R.page(justiceCaseDimensions); } }4.2 Service/Mapper 层
无需任何分页相关代码,正常返回List即可。
二、方案二:MyBatis-Plus 原生 IPage 分页(官方推荐)
1. 方案概述
IPage/Page是 MyBatis-Plus官方原生提供的分页对象,直接通过方法入参 / 返回值实现分页,代码更简洁、规范,是新项目首选方案。
2. 核心原理
- 前端传递分页参数(page、pageSize),SpringMVC 自动封装为
Page对象; - 将
Page对象传入查询方法,MyBatis-Plus 自动完成分页查询; - 直接返回
IPage对象,自带总条数、总页数、当前页数据等完整分页信息。
3. 适用场景
- 新项目开发、遵循官方规范
- 需要清晰的分页参数传递
- 简化代码结构,降低维护成本
4. 完整代码示例
4.1 Controller 层(业务接口)
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; /** * 案件维度管理 Controller */ @RestController @RequestMapping("/justice/case/dimension") public class JusticeCaseDimensionController { @Resource private CaseDimensionContext caseDimensionContext; /** * 按范围查询案件聚合维度(账龄+批次号/被告) * 方案二:原生 IPage 分页(官方推荐) */ @GetMapping("/selectCaseDimensionByScope") public R<IPage<JusticeCaseDimension>> selectCaseDimensionByScope( // 分页参数:自动接收 page、pageSize Page<JusticeCaseDimension> page, JusticeCaseDimensionQuery caseDimensionQuery ) { // 1. 直接传入 Page 对象,返回 IPage 分页结果 IPage<JusticeCaseDimension> pageResult = caseDimensionContext.selectCaseDimensionByScope(page, caseDimensionQuery); // 2. 直接返回原生分页对象 return R.ok(pageResult); } }4.2 Service 层
/** * Service 层方法 */ public IPage<JusticeCaseDimension> selectCaseDimensionByScope(Page<JusticeCaseDimension> page, JusticeCaseDimensionQuery query) { // 调用 Mapper,直接返回 IPage return baseMapper.selectCaseDimensionByScope(page, query); }4.3 Mapper 层
/** * Mapper 层方法 */ IPage<JusticeCaseDimension> selectCaseDimensionByScope(Page<JusticeCaseDimension> page, @Param("query") JusticeCaseDimensionQuery query);三、两种分页方案核心对比
| 对比维度 | PageUtils 工具类分页 | 原生 IPage 分页 |
|---|---|---|
| 官方推荐度 | 非官方,项目自定义封装 | ✅ MyBatis-Plus 官方标准 |
| 代码侵入性 | 无侵入,无需修改原有接口 | 轻度侵入,需传入 Page 对象 |
| 代码简洁度 | 需手动开启分页 + 封装结果 | 一步到位,代码极简 |
| 分页信息 | 工具类自动封装 | 自带完整分页信息(总条数 / 总页数) |
| 适用项目 | 老项目、存量系统改造 | 新项目、标准化开发 |
| 学习成本 | 低(直接调用工具方法) | 低(原生对象,无额外学习) |
四、最佳实践建议
- 新项目优先使用 原生 IPage 分页:符合官方规范,代码更易维护,团队协作成本更低;
- 老项目保留 PageUtils 分页:无需大规模改造代码,兼容现有业务逻辑;
- 统一项目规范:一个项目中只使用一种分页方案,避免代码风格混乱。
