PageHelper 是Mybaties中的一个分页插件。其maven坐标

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>

目前以更新到5.1 ,新的版本好像和以前的版本有些差别 这里分析下以前的版本

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.3</version>
</dependency>

其和Mybaties的配置整合不累赘。只看看如何实现分页的原理。

先说如果在代码中使用 ,很简单如下,一行代码 ,在查询的时候就自动实现分页:

PageHelper.startPage(params.getPageIndex(), params.getPageSize(), true, true);

其startPage方法重载 :

跟踪代码 进入到PageHelper这个类 看到这个类继承了Interceptor 接口,这个接口是Mybaties 提供的

public class PageHelper implements Interceptor {
//sql工具类
private SqlUtil sqlUtil;
//属性参数信息
private Properties properties;
//配置对象方式
private SqlUtilConfig sqlUtilConfig;
//自动获取dialect,如果没有setProperties或setSqlUtilConfig,也可以正常进行
private boolean autoDialect = true;
//运行时自动获取dialect
private boolean autoRuntimeDialect;
//多数据源时,获取jdbcurl后是否关闭数据源
private boolean closeConn = true;
//缓存
private Map<String, SqlUtil> urlSqlUtilMap = new ConcurrentHashMap<String, SqlUtil>();
  ...
public interface Interceptor {

  Object intercept(Invocation invocation) throws Throwable;

  Object plugin(Object target);

  void setProperties(Properties properties);

}
可以看到 Interceptor 类中有个拦截方法intercept ,这个方法就应该是拦截器的执行方法 。继续跟踪这个方法在哪里有引用 。发现只在类plugin类有引用 

可以看到在method.invoke 执行之前 ,拦截器执行了拦截方法 ,而 pageHelper这个类就是个拦截器 。再看看Plugin这个类 实现了动态代理 的接口 InvocationHandler 。其私有构造方法在静态方法wrap中调用 ,说明这能通过wrap这个方法获取Plugin实例,wrap方法对参数target做了个动态代理 。所以说target执行方法是通过代理 Plugin 执行invoke方法 。

那么wrap方法中的target 又是什么呢 ???。wrap方法又是在什么时候调用的呢 ?一层一层的跟踪 如下代码 。

又回到了 pageHelp 这个类,在类plugin方法中调用了wrap方法,而且target只有在属于Executor 的时候把target做了代理。跟踪代码发现Plugin方法又在拦截器链InterceptorChain方法pluginAll调用

pluginAll 就是把target这个类按拦截器的数量做了多次对plugin的代理 ,而每个plugin中都有一个不同的拦截器 Interceptor。而target在这可以把它 看做是执行器Executor 了 。因为前面说过只对Executor 拦截,再看看pluginAll方法的引用, 在类 Configuration如下

可以看到在Configuration创建  Executor 、ParameterHandler、ResultSetHandler、StatementHandler 都有对做代理 ,对拦截器进行拦截执行。但是pageHelp只对Executor 做了代理 。回过头来看看拦截器PageHelp做了什么 ?

/**
* Mybatis拦截器方法
*
* @param invocation 拦截器入参
* @return 返回执行结果
* @throws Throwable 抛出异常
*/
public Object intercept(Invocation invocation) throws Throwable {
if (autoRuntimeDialect) {
SqlUtil sqlUtil = getSqlUtil(invocation);
return sqlUtil.processPage(invocation);
} else {
if (autoDialect) {
initSqlUtil(invocation);
}
return sqlUtil.processPage(invocation);
}
}

方法最终就是通过sqlUtil在执行sql中加了分页参数  。完成分页 。

mybatis分页插件PageHelper源码浅析的更多相关文章

  1. Java SSM框架之MyBatis3(三)Mybatis分页插件PageHelper

    引言 对于使用Mybatis时,最头痛的就是写分页,需要先写一个查询count的select语句,然后再写一个真正分页查询的语句,当查询条件多了之后,会发现真不想花双倍的时间写count和select ...

  2. 基于Mybatis分页插件PageHelper

    基于Mybatis分页插件PageHelper 1.分页插件使用 1.POM依赖 PageHelper的依赖如下.需要新的版本可以去maven上自行选择 <!-- PageHelper 插件分页 ...

  3. (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示

    http://blog.csdn.net/yerenyuan_pku/article/details/72774381 上文我们实现了展示后台页面的功能,而本文我们实现的主要功能是展示商品列表,大家要 ...

  4. Mybatis分页插件PageHelper的配置和使用方法

     Mybatis分页插件PageHelper的配置和使用方法 前言 在web开发过程中涉及到表格时,例如dataTable,就会产生分页的需求,通常我们将分页方式分为两种:前端分页和后端分页. 前端分 ...

  5. Mybatis分页插件PageHelper使用

    一. Mybatis分页插件PageHelper使用  1.不使用插件如何分页: 使用mybatis实现: 1)接口: List<Student> selectStudent(Map< ...

  6. Mybatis学习---Mybatis分页插件 - PageHelper

    1. Mybatis分页插件 - PageHelper说明 如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件. 该插件目前支持Oracle,Mysql,MariaDB,S ...

  7. Mybatis分页插件PageHelper的实现

    Mybatis分页插件PageHelper的实现 前言 分页这个概念在做web网站的时候很多都会碰到 说它简单吧 其实也简单 小型的网站,完全可以自己写一个,首先查出数据库总条数,然后按照分页大小分为 ...

  8. Mybatis分页插件-PageHelper的使用

    转载:http://blog.csdn.net/u012728960/article/details/50791343 Mybatis分页插件-PageHelper的使用 怎样配置mybatis这里就 ...

  9. springmvc mybatis 分页插件 pagehelper

    springmvc mybatis 分页插件 pagehelper 下载地址:pagehelper 4.2.1 , jsqlparser 0.9.5 https://github.com/pagehe ...

随机推荐

  1. makefile编译子目录

    make子目录常用方法 一般是 SUB_DIR = lib_src service .PHONY: subdirs $(SUB_DIR) subdirs: $(SUB_DIR) $(SUB_DIR): ...

  2. flask cache

    http://brunorocha.org/python/flask/using-flask-cache.html 如何在大项目中使用cache 新建全局cache.py cache = Cache( ...

  3. Go语言核心36讲(Go语言实战与应用三)--学习笔记

    25 | 更多的测试手法 在本篇文章,我会继续为你讲解更多更高级的测试方法.这会涉及testing包中更多的 API.go test命令支持的,更多标记更加复杂的测试结果,以及测试覆盖度分析等等. 前 ...

  4. Navicat15最新版本破解 亲测可用!!!(Navicat Premium 注册出现 No All Pattern Found! File Already Patched)

    1.下载Navicat Premium官网https://www.navicat.com.cn/下载最新版本下载安装 2.本人网盘链接:https://pan.baidu.com/s/1ncSaxId ...

  5. script标签引入vue方式开发如何写组件

    title: script标签引入vue方式开发如何写组件 date: 2020-05-08 sidebarDepth: 2 tags: vue 组件 script 标签 categories: vu ...

  6. Modelsim仿真新手入门最详细教程

    2021年11月15日 00 安装包/版本 我是提前在网上下好的(但这一点也给我的实验造成了"麻烦"),用的是Modelsim SE-64 2020.4版本的,学校实验室的似乎不同 ...

  7. Django 小实例S1 简易学生选课管理系统 4 实现登录页面

    Django 小实例S1 简易学生选课管理系统 第4节--实现登录页面 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 本文涉及到的新的额外知识点: ...

  8. SpringCloud微服务实战——搭建企业级开发框架(十七):Sentinel+Nacos配置持久化

      Sentinel Dashboard中添加的规则是存储在内存中的,我们的微服务或者Sentinel一重启规则就丢失了,现在我们将Sentinel规则持久化配置到Nacos中,在Nacos中添加规则 ...

  9. oracle中是否有except函数: select * from a except select * from b

    除外: oracle没有except这个关键字,这个关键字属于sqlserver ,在oracle里,他叫minus,与except是一个意思. select a.code OrgId, b.code ...

  10. Type mismatch:

    Type mismatch: cannot convert from java.sql.PreparedStatement to com.mysql.jdbc.PreparedStatement im ...