MyBatis分页神器PageHelper深度解析

PageHelper 是一个优秀的 MyBatis 分页插件,它通过简单的拦截器机制,实现了对 MyBatis 查询的物理分页(而非内存分页),极大简化了分页代码的编写。而 PageHelper 扩展 通常指的是在其核心功能基础上,为特定框架(如 Spring Boot)或特定需求(如简化配置、增强功能)提供的增强模块或使用方式。

以下是对 PageHelper 及其常见扩展的介绍:


一、核心 PageHelper 功能回顾

  1. 核心原理
    • 基于 MyBatis 的 Interceptor 接口,拦截 Executor 的查询方法。
    • 在执行目标 SQL 前,自动分析原 SQL 并生成 COUNT 查询(获取总数)和添加了物理分页(如 LIMIT, ROWNUM)的查询。
  2. 基本用法
    // 在查询方法前调用,设置分页参数
    PageHelper.startPage(pageNum, pageSize); // pageNum: 页码, pageSize: 每页条数
    // 紧接着的第一个 MyBatis 查询方法会被分页
    List<Country> list = countryMapper.selectAll();
    // 用 PageInfo 包装结果,包含分页详细信息(总记录数、总页数、当前页等)
    PageInfo<Country> pageInfo = new PageInfo<>(list);
    
  3. 主要优点
    • 简单:一行代码启动分页。
    • 高效:物理分页,数据库压力小。
    • 通用:支持多种数据库(MySQL, Oracle, PostgreSQL, SQLServer 等)。
    • 灵活:支持多种参数传递方式(startPage 方法、RowBounds 参数)。
    • 丰富信息PageInfo 对象提供全面的分页信息。

二、重要的 PageHelper 扩展

  1. pagehelper-spring-boot-starter

    • 定位:官方提供的 Spring Boot 自动配置 Starter。
    • 核心价值
      • 零配置/简化配置:只需引入依赖,大部分情况下无需任何额外配置即可使用。
      • 自动注入:自动配置 PageHelper 拦截器并将其注册到 MyBatis SqlSessionFactory 中。
      • 约定优于配置:遵循 Spring Boot 的配置习惯,可以通过 application.properties/application.yml 轻松配置插件属性。
    • 依赖 (Maven):
      <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>最新版本</version> <!-- 请替换为当前最新版本,如 2.1.0 -->
      </dependency>
      
    • 常用配置示例 (application.yml):
      pagehelper:helper-dialect: mysql  # 指定数据库方言(通常可自动检测)reasonable: true       # 启用合理化:pageNum<=0 时设为 1,pageNum>总页数时设为最后一页support-methods-arguments: true # 支持通过 Mapper 接口参数传递分页参数params: count=countSql  # 配置 COUNT 查询的返回值 keypage-size-zero: true    # 允许 pageSize=0 时查询所有结果(返回 PageInfo,total=实际条数)
      
    • 使用:在 Spring Boot 项目中引入该 starter 后,直接在 Service 或 Controller 中使用 PageHelper.startPage(pageNum, pageSize) 即可。
  2. PageHelper 的参数模式扩展

    • 核心功能扩展:除了 PageHelper.startPagePageHelper 本身支持更灵活的参数传递:
      • 方法参数传递 (需配置 support-methods-arguments: true):
        // Mapper 接口
        List<User> selectUsers(@Param("name") String name, @Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
        
        // Service 调用 (无需显式调用 startPage)
        List<User> users = userMapper.selectUsers("John", 2, 10);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        
      • RowBounds 参数传递 (较旧方式,优先级低于 startPage):
        List<User> users = sqlSession.selectList("selectUsers", null, new RowBounds(2, 10));
        
  3. PageInfo 的增强

    • 虽然 PageInfo 本身是核心的一部分,但它提供的丰富分页信息是其强大扩展性的体现:
      • getTotal():总记录数。
      • getPages():总页数。
      • getPageNum():当前页码。
      • getPageSize():每页条数。
      • getList():当前页的数据列表。
      • isIsFirstPage()/isIsLastPage():是否第一页/最后一页。
      • hasPreviousPage()/hasNextPage():是否有上一页/下一页。
      • getPrePage()/getNextPage():上一页/下一页页码。
      • getNavigatepageNums():所有导航页码(如 [1,2,3,4,5])。
    • 这极大地简化了将分页信息返回给前端的工作。

三、使用 PageHelper 扩展的注意事项

  1. PageHelper.startPage 的调用位置
    • 必须紧挨着需要分页的 MyBatis 查询方法调用之前。中间不能有其它可能触发查询的操作(如调用另一个查询方法)。
  2. 线程安全
    • PageHelper.startPage 内部使用 ThreadLocal 保存分页参数。这意味着它是线程安全的,但也意味着分页参数只对当前线程的紧接着的下一次查询有效。查询完成后,ThreadLocal 会被自动清理。在异步、多线程或复杂调用链中要特别注意调用时机。
  3. PageInfo 的构造
    • 传入 PageInfo 构造器的 List 对象,必须是 PageHelper.startPage 后执行分页查询返回的那个 List。这个 List 实际上是一个 Page 对象(实现了 List 接口),包含了分页信息。如果用其他 List 构造 PageInfo,信息会错误。
  4. 数据库方言 (dialect)
    • 确保配置正确的数据库方言,或让插件自动检测(通常可行)。错误的方言会导致生成错误的分页 SQL。
  5. reasonable 参数
    • 建议开启 (reasonable: true),避免用户传入非法页码导致空数据或错误。
  6. page-size-zero
    • 如果业务有“pageSize=0 时返回所有数据”的需求,配置 page-size-zero: true。注意此时 PageInfototal 是实际数据条数(可能很大),pages 为 1。
  7. 避免与 RowBounds 混用
    • 如果同时使用了 PageHelper.startPageRowBounds 参数,PageHelper.startPage 的优先级更高。

四、总结

  • 核心 PageHelper:提供了 MyBatis 物理分页的核心拦截能力和基础 API (startPage, PageInfo)。
  • 关键扩展 pagehelper-spring-boot-starter:极大简化了在 Spring Boot 项目中的集成和使用,是当前最推荐的使用方式,实现了开箱即用。
  • 参数模式扩展:提供 startPage 之外更灵活的传参方式(方法参数、RowBounds),适应不同编码风格。
  • PageInfo 对象:作为核心功能的一部分,提供了强大的分页信息封装能力,是返回给前端的理想数据结构。

选择建议:对于 Spring Boot 项目,直接使用 pagehelper-spring-boot-starter 是最佳实践。充分利用其自动配置和属性配置,结合 PageHelper.startPagePageInfo,可以非常高效、简洁地实现功能强大且信息完整的分页功能。理解核心原理和注意事项(尤其是 startPage 的调用位置和线程特性)是避免踩坑的关键。

如果你有特定的 PageHelper 扩展需求(比如集成到其他框架,或者自定义分页逻辑),可以进一步探讨其 SPI 机制或自定义拦截器实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91805.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【2025/07/19】GitHub 今日热门项目

GitHub 今日热门项目 &#x1f680; 每日精选优质开源项目 | 发现优质开源项目&#xff0c;跟上技术发展趋势 &#x1f4cb; 报告概览 &#x1f4ca; 统计项&#x1f4c8; 数值&#x1f4dd; 说明&#x1f4c5; 报告日期2025-07-19 (周六)GitHub Trending 每日快照&#x1f55…

【数据结构】二叉树初阶详解(一):树与二叉树基础 + 堆结构全解析

文章目录&#x1f4dd;前言&#x1f320;树的概念和结构&#x1f309;树的概念&#x1f309;树的相关概念&#x1f309;树的表示&#x1f320;二叉树概念及结构&#x1f309;二叉树的概念&#x1f309;特殊的二叉树&#x1f309;二叉树的性质&#x1f320;二叉树顺序结构及实现…

Flutter基础(前端教程①⑤-API请求转化为模型列成列表展示实战)

models/post_model.dart定义 Post 数据模型包含 fromJson() 方法用于解析 JSONcontrollers/post_controller.dart管理帖子数据的获取和状态使用 http 包请求 API通过 RxList 和 RxBool 实现响应式状态管理views/post_list_view.dart展示帖子列表的 UI使用 Obx 监听状态变化包含…

第十五届全国大学生数学竞赛初赛试题(非数学专业类A卷)

第十五届全国大学生数学竞赛初赛试题(非数学专业类A卷) 文章目录第十五届全国大学生数学竞赛初赛试题(非数学专业类A卷)题目速览逐题详解题目速览 求极限&#xff1a; lim⁡x→3x39−62−x3−23.\lim\limits_{x \to 3} \frac{\sqrt{x^3 9} - 6}{2 - \sqrt{x^3 - 23}} \rule{2…

ROS1/Linux——Ubuntu、ROS1虚拟机环境配置

ROS1/Linux——Ubuntu、ROS1虚拟机环境配置 文章目录ROS1/Linux——Ubuntu、ROS1虚拟机环境配置编辑时间&#xff1a;系统环境Linux镜像下载Ubuntu相关链接iso镜像下载VMware操作虚拟机安装步骤基础设置设置语言设置窗口分辨率、图标大小等终端固定在左侧栏显示隐藏文件夹其他问…

万字解析LVS集群

一、集群和分布式介绍1.1、诞生的原因单台设备 “又贵又弱又容易挂”&#xff0c;扛不住现代业务的 “海量访问、海量数据、复杂计算”&#xff1b;集群 / 分布式让多台设备 “抱团干活”&#xff0c;分担压力&#xff08;流量、存储、计算&#xff09;&#xff0c;还能 “坏了…

关于博客后续内容会以xmind内容转markdown格式来呈现

自己感觉不正确的地方 一直感觉学啥东西记到博客里&#xff0c;这样就方便后续回顾或者查找 但csdn貌似不适合全局搜索&#xff0c;也就是我居然先要知道我对应的模糊点对应到哪篇文章&#xff0c;然后再到那篇文章里找&#xff0c;简直麻烦死了&#xff0c;而且另外一个毛病是…

Python - 数据分析三剑客之Pandas

阅读前可参考NumPy文章 https://blog.csdn.net/MinggeQingchun/article/details/148253682https://blog.csdn.net/MinggeQingchun/article/details/148253682 ‌Pandas是Python中一个强大的开源数据分析库&#xff0c;专门用于处理结构化数据&#xff08;如表格、时间序列等&…

深度解析:Python实战京东资产拍卖平台爬虫,从ID抓取到详情数据落地

深度解析:Python实战京东资产拍卖平台爬虫,从ID抓取到详情数据落地 对爬虫、逆向感兴趣的同学可以查看文章,一对一小班教学(系统理论和实战教程)、提供接单兼职渠道:https://blog.csdn.net/weixin_35770067/article/details/142514698 文章目录 深度解析:Python实战京东…

ServletConfig 接口详解

ServletConfig 接口详解 1. 核心概念 ServletConfig 是 Servlet 规范中定义的核心接口&#xff0c;用于在 Servlet 初始化阶段向 Servlet 传递配置信息。每个 Servlet 都有自己独立的 ServletConfig 对象。 2. 关键特性特性说明唯一性每个 Servlet 实例拥有独立的 ServletConfi…

Maven学习总结(62)—— Maven 打包瘦身和提速解决方案

臃肿的 Maven 项目 在 Java 项目开发中,Maven 作为强大的项目管理和构建工具,极大地简化了依赖管理和项目构建过程。但随着项目的不断演进,依赖的 Jar 包越来越多,我们的 Maven 项目也逐渐变得臃肿不堪。曾经,我参与维护一个大型的 Spring Boot 项目,随着业务功能的不断…

【Qt开发】Qt的背景介绍(三)-> 认识Qt Creator

目录 1 -> Qt Creator概览 2 -> 使用Qt Creator创建项目 2.1 -> 新建项目 2.2 -> 选择项目模板 2.3 -> 选择项目路径 2.4 -> 选择构建系统 2.5 -> 填写类信息设置界面 2.6 -> 选择语言和翻译文件 2.7 -> 选择Qt套件 2.8 -> 选择版本控…

HTML5中的自定义属性

自定义属性&#xff08;Custom Attributes&#xff09; 允许在标准 HTML 属性之外&#xff0c;为元素添加额外的元数据&#xff08;metadata&#xff09;。 1. 标准方式&#xff1a;data-* 属性 HTML5 引入了 data-* 前缀的自定义属性规范&#xff0c;所有以 data- 开头的属性都…

前端项目利用Gitlab CI/CD流水线自动化打包、部署云服务

叠甲前言 本文仅作为个人学习GitLab的CI/CD功能记录&#xff0c;不适合作为专业性指导&#xff0c;如有纰漏&#xff0c;烦请君指正。 Gitlab的CI/CD做什么用的 自工作以来&#xff0c;去过大大小小公司&#xff0c;有一些公司技术人员专业性欠佳&#xff0c;每当产品经理或…

基于typescript严格模式以实现undo和redo功能为目标的命令模式代码参考

下面是一个完整的、严格模式下的 TypeScript 实现&#xff0c;包含 CommandManager、Command 和 CompositeCommand 类&#xff0c;支持 undo/redo 功能。完整实现代码1. Command 接口和基类// src/commands/ICommand.ts export interface ICommand {execute(): void;undo(): vo…

2022年CIE SCI2区TOP,NSGA-II+直升机-无人机搜救任务分配,深度解析+性能实测

目录1.摘要2.数学模型3.求解方法4.结果展示5.参考文献6.代码获取7.算法辅导应用定制读者交流1.摘要 无人机任务分配对于保障搜救活动高效有序开展具有重要意义&#xff0c;但现有研究较少考虑无人机作业环境与性能对任务分配的影响。针对低空风场和地形因素对无人机能耗与性能…

暑期算法训练.4

目录 15.力扣 904.水果成篮 15.1 题目解析&#xff1a; 15.2 算法思路&#xff1a; 15.2.1 暴力解法&#xff1a; 15.2.1 滑动窗口 15.3代码演示&#xff1a; 15.4 总结反思&#xff1a; 16 力扣 438.找出字符串中所有字母的异位词 16.1 题目解析&#xff1a; 16.2算法…

关于个人博客系统的测试报告

1&#xff09;项目背景2&#xff09;项目功能介绍 登陆写博客/编辑已存在博客删除博客注销 2&#xff09;基于项目功能设计相关测试用例3&#xff09;基于测试用例编写自动化测试 准备工作登陆界面相关博客首页相关博客详情页相关编辑博客相关删除博客相关注销相关 4&#xff0…

Spring Boot 与微服务详细总结

一、Spring Boot 核心概述 Spring Boot 是简化 Spring 应用开发的框架&#xff0c;作为 Spring 技术栈的整合方案和 J2EE 开发的一站式解决方案&#xff0c;其核心优势体现在&#xff1a; 快速创建独立运行的 Spring 项目&#xff0c;轻松集成主流框架内置 Servlet 容器&…

轻松上手:从零开始启动第一个 Solana 测试节点

嗨&#xff0c;各位技术爱好者们&#xff01; 大家是否对 Solana 的“光速”交易处理能力感到好奇&#xff1f;或者你是一名开发者&#xff0c;正准备在 Solana 上构建下一个杀手级 dApp&#xff1f;无论大家是出于学习目的还是实际开发需求&#xff0c;亲手运行一个 Solana 节…