pageHelper的使用与源码分析

2023-11-18

pageHelper作为Mybatis最好用的分页插件,自然受到极大多数人的追捧。而这里想要尽量阐述清楚pageHelper的具体使用步骤,实现的背后原理,以及与原始分页写法相比有什么优缺点等。

一、使用步骤

在这里,使用SpringBoot来集成pageHelper作为演示。

  1. 引入Maven依赖
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>
  1. 查询所有记录的SQL

image-20201222115942108

  1. 在控制层加入PageHelper,表示查前十条
PageInfo<User> getList(User user){
    PageHelper.startPage(1, 10);
    return new PageInfo<User>(userService.getList(user));
}

image-20201222142139753

至此,基本的pageHelper分页使用就是这样,后面可以自己再做些封装等。

二、分页原理

​ 通过第一部分的应用实战,我们在返回结果中可以看到total总数,以及pageNumpageSize等其他分页属性,这些属性的结果都是怎么返回的呢,PageHelper.startPage()这行代码背后又做了哪些事情呢。

1. 统计总数

​ 在mapper的xml文件中,我并没有写统计总数的count方法,但是pageHelper能够自动计算出来。经过分析是因为默认在列表查询的方法前包装一个select count(1),且select的id为xxxx_COUNT,xxxx为查询List的id,即效果类似于:

<select id="getPageList" resultMap="BaseResultMap" >
    select id, name from user
</select>

<select id="getPageList_COUNT" resultType="Long" >
    select count(1) from user
</select>
2. 源码分析

当使用PageHelper.startPage(1, 10);的时候,我们通过查看源码发现,分页参数通过传递达到了PageHelper的父类PageMethod的startPage()方法。

image-20201222150223078

有多个startPage()重载方法,且经过观察发现,所有的startPage()均指向public static Page startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero){},目的是为了构造一个Page对象,且作为ArrayList的子类,最终返回构造好的Page对象:

protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal();
protected static boolean DEFAULT_COUNT = true;

public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
    Page<E> page = new Page(pageNum, pageSize, count);
    page.setReasonable(reasonable);
    page.setPageSizeZero(pageSizeZero);
    Page<E> oldPage = getLocalPage();
    if (oldPage != null && oldPage.isOrderByOnly()) {
        page.setOrderBy(oldPage.getOrderBy());
    }

    setLocalPage(page);
    return page;
}
public class Page<E> extends ArrayList<E> implements Closeable {
    private static final long serialVersionUID = 1L;
    private int pageNum;
    private int pageSize;
    private long startRow;
    private long endRow;
    private long total;
    private int pages;
    private boolean count;
    private Boolean reasonable;
    private Boolean pageSizeZero;
    private String countColumn;
    private String orderBy;
    private boolean orderByOnly;
    private BoundSqlInterceptor boundSqlInterceptor;
    private transient Chain chain;
    ...
}

​ 分页参数是跟ThreadLocal本地线程绑定的,确保当前线程中有一个Page对象。

​ 由于是在SpringBoot中,所以我们找到PageHelper的自动配置类PageHelperAutoConfiguration

image-20201222155306271

​ 其中,addPageInterceptor()方法主要加载了配置文件中我们自定义的属性,以及PageInterceptor拦截器的实例化。

image-20201222155708090

通过这个拦截器即可在数据库操作阶段进行切入操作,我们进入到PageInterceptor中查看实现过程,其中PageInterceptor实现了Interceptor接口

image-20201222162725394

这里的count就是统计总数的实现。其中主要方法是通过Dialect这个接口来实现的,由于数据库类型不一致所以实现类和方法均有差异,故可以看到实现类有很多:

image-20201222164342855

PageInterceptor中使用的Dialect默认实现类是PageHelper,在PageHelper中使用的具体实现类其实都交给了PageAutoDialect。

image-20201222164802960

最后回到PageInterceptor的intercept()方法中,

ExecutorUtil.pageQuery(this.dialect, executor, ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);

具体的分页查询实现就在ExecutorUtil工具类的pageQuery()方法

image-20201222170855663

三、总结

​ 最开始对一句代码就能进行分页表示好奇,通过查阅相关资料了解源码实现后对整个pageHelper有了大概的理解。不过也只是了解了一点皮毛,更多的是对源码分析敲砖。

参考资料:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pageHelper的使用与源码分析 的相关文章

随机推荐

  • Windows11如何正确修改电脑用户名——解决修改用户名之后无法找到文件路径,路径不存在问题——用Registry Workshop批量操作注册表

    c users 后面是中文会有什么影响 很多人在刚拿到电脑的时候 注册用户名的时候直接填的中文 对一名程序员来说 用户名是中文 有时候在程序运行的过程中会产生非常多的麻烦 解决办法 想要了解第三点的命令的可以看这里http t csdn c
  • RocketMQ-源码解读与调试

    源码环境搭建 源码拉取 RocketMQ的官方Git仓库地址 GitHub apache rocketmq Mirror of Apache RocketMQ 可以用git把项目clone下来或者直接下载代码包 也可以到RocketMQ的官
  • Java设计模式-结构型设计模式-适配器模式

    Java设计模式 结构型设计模式 适配器模式 从这一专栏开始将学习设计模式 上课学习和自己总结归纳的笔记将总结出来供大家参考 参考书籍 设计模式就该这样学 其他文章 Java设计模式 UML类图 Java设计模式 七大架构设计原则 开闭原则
  • 机器学习NLP参考文章

    本站整理了一些NLP的入门资料参考 建议初学者看看 需要复制链接在浏览器里打开 1 通过kaggle比赛学习机器学习文本分类方法https zhuanlan zhihu com p 34899693 utm medium social ut
  • 宋浩高等数学笔记(八)向量代数与空间解析几何

    本章知识点并不难理解 但是公式与名词属于非常多 记忆时需重点对待
  • Java GUI编程——在线聊天室

    引言 综合应用Java的GUI编程和网络编程 实现一个能够支持多组用户同时使用的聊天室软件 该聊天室具有比较友好的GUI界面 并使用C S模式 支持多个用户同时使用 用户可以自己选择加入或者创建房间 和房间内的其他用户互发信息 文字和图片
  • Web前端的优点有什么?为什么前端可以这么火?

    今天小编要跟大家分享的文章是关于web前端的优点有哪些 为什么Web前端可以这么火 相信小伙伴们对Web前端并不陌生 那么你知道Web前端的有点都有哪些吗 下面就让我们一起来看一看吧 HTML5是唯一一个通吃PC Mac iPhone iP
  • oracle两个日期的月份间隔,Oracle 计算两个日期间隔的天数、月数和年数

    在Oracle中计算两个日期间隔的天数 月数和年数 一 天数 在Oracle中 两个日期直接相减 便可以得到天数 1 select to date 08 06 2015 mm dd yyyy to date 07 01 2015 mm dd
  • 三招搞定你的ubuntu安全问题

    本篇主要介绍以下三个部分 反病毒引擎clamav的安装和使用 ubuntu ufw限制访问地址 ubuntu用户连接失败锁定指定时间 反病毒引擎clamav的安装和使用 简介 ClamAV是一款开源的反病毒引擎 用于检测病毒 特洛伊木马 恶
  • IT行业里的热门技术和项目分享

    随着科技的发展 IT行业中涌现出了很多热门技术 其中最具代表性的包括人工智能和机器学习 云计算和云原生技术 大数据和数据分析 容器化技术和Kubernetes 前端框架和组件库等 此外 也有一些热门IT技术项目备受关注 比如Apache K
  • jdk报错

    Syntax error annotations are only available if source level is 1 5 or greater解决方法 原创 2016年07月18日 14 13 39 ul class artic
  • Java内存分配全面浅析

    本文将由浅入深详细介绍Java内存分配的原理 以帮助新手更轻松的学习Java 这类文章网上有很多 但大多比较零碎 本文从认知过程角度出发 将带给读者一个系统的介绍 进入正题前首先要知道的是Java程序运行在JVM Java VirtualM
  • 多维随机变量及其分布(四):

    一 二维随机变量及其分布函数 1 二维随机变量 设随机变量 Z X Y 则有 Z X Y 一个随机变量是有两个随机变量决定的 2 联合分布函数的基本性质 单调性 F x y 分别对x 或y是单调不减的 即 对任意固定的y 当 x1 lt x
  • 【SPI】STM32 SPI 双机通信,SPI从机模式使用

    文章目录 一 SPI主机配置 二 SPI从机配置 三 双机通信 1 轮询 中断 低速 2 轮询 DMA 低速 3 DMA DMA 高速 4 开启CRC校验 自选 四 遇到的问题 1 高速使用时 程序卡死 或者数据出错 已解决 2 数据莫名其
  • html制作日程安排,在线日程安排怎样做?日程表在线制作工具

    在线日程安排怎样做 日程表在线制作工具 在线日程安排怎样做 每日仅有二十四小时 可在一天我们要做的事却太多 每日忙的晕头转向 身心俱疲 这可咋办啊 戴尔 麦康基说过 计划的订制比计划本身更为重要 因此可见 订制好每日的行程安排是不可或缺的
  • 详述String类的equals方法

    详述String类的equals方法 1 两个String类的对象采取直接赋值 ublic class Test public static void main String args String name1 Tom String nam
  • java基础语法之面向对象

    面向对象 面向对象是一种编程思想 与之对应的是面向过程 区别 面向过程 POP 强调的是功能 面向对象 OOP 强调的是带有具体功能的对象 面向对象的优点 提高代码复用性 降低代码间的耦合度 提升代码维护性 三大特征 封装 继承 多态 一
  • 六种黑客入侵手机的常见方式

    六种黑客入侵手机的常见方式 在移动网络科技高速发展的今天 我们每个人的手机都有可能成为黑客攻击的对象 下面为大家介绍6种黑客入侵手机的常见方式 希望能够帮助大家避免手机被不对象攻击 1 网络钓鱼攻击 网络钓鱼攻击非常普遍 那是因为它们非常有
  • 磁盘空间重分配

    root localhost df h Filesystem Size Used Avail Use Mounted on dev mapper VolGroup lv root 50G 47G 16M 100 lv root满了 tmpf
  • pageHelper的使用与源码分析

    文章目录 一 使用步骤 二 分页原理 1 统计总数 2 源码分析 三 总结 pageHelper作为Mybatis最好用的分页插件 自然受到极大多数人的追捧 而这里想要尽量阐述清楚pageHelper的具体使用步骤 实现的背后原理 以及与原