我们终于发现了PageHelper中执行修改SQL语句的方法:MySqlDialect.getPageSql。

通过这几天的文章,我们了解到了PageHelper是通过拦截Mybatis中的Executor来实现的。之前我们只关注PageHelper的执行细节,今天我们来看一下PageHelper的整体文件结构:

整个项目的包路径为:​​com.github.pagehelper​​中。

拦截器

包中首先是两个拦截器类:​​PageInterceptor ​​​以及 ​​QueryInterceptor​​。两个类的注解中均为

@Signature(type = Executor.class, method = "query"....

即并且均拦截了Mybatis中4个参数与6个参数的Executor。这一点我们从PageHelper的​​wiki​​中也能获取到。

接口

我们在包中还发现了几个接口:

​Dialect​​:数据库方言,针对不同数据库进行实现。


​AutoDialect<K>​​​: 自动获取方言,其中​​<K>​​为缓存key类型。


​BoundSqlInterceptor​​: BoundSql 处理器。其中还有一个内部接口:


​Chain​​:处理器链,可以控制是否继续执行。


​Constant​​: 常量接口。


​IPage​​: 接口,定义了三个方法:getPageNum、getPageSize、getOrderBy。


​ISelect​​: 分页查询接口,定义了一个方法doSelect()。

 继承自Mybatis中的类

​PageRowBounds​​​: 它继承自​​org.apache.ibatis.session.RowBounds​​​,包含属性值​​NO_ROW_OFFSET​​​,​​NO_ROW_LIMIT​​​,​​offset​​​, ​​limit​​​等,并扩展了字段​​total​​​,​​count​​。

 异常处理类:

PageException:继承自RuntimeException。

其他类:

​Page​​​:我们在代码解读中见过多次,知道是通过它来保存分页参数的,并且程序执行过程中是通过​​ThreadLocal<Page>​​​线程局部变量来做局部传参,其中保存的参数有:pageNum页码, pageSize页码大小, startRow起始行, endRow末行, total总数, pages总页数, 布尔类型count表示是否包含count查询,布尔类型reasonable表示分页是否合理化,其他参数包括​​pageSizeZero​​​, ​​countColumn​​​,​​orderBy​​​,​​orderByOnly​​​,sql拦截器​​BoundSqlInterceptor​​​, ​​BoundSqlInterceptor.Chain​​​,分页实现类​​dialectClass​​。

在​​dialectClass​​注释中写道

分页实现类,可以使用 {@link com.github.pagehelper.page.PageAutoDialect} 类中注册的别名,例如 "mysql", "oracle"

 等阐述到如何绑定mysql时我们再剖析来阐述。

题外话

参加工作后接触拦截器是在国产开源项目​​Jfinal​​中,其中通过interceptor,before,clear来控制接口的拦截器,当时觉得很神奇(现在也觉得蛮神奇)。

拦截器主要是通过使用反向代理或其他方式,实现控制接口中的拦截器执行方式及其顺序等。

规范名称叫AOP,面向切面编程,有时间写两篇实现拦截器的文章,一起学习!