admin 管理员组

文章数量: 887053


2024年2月7日发(作者:墨茶真人长什么样子)

age原理

PageHelper是一款开源的MyBatis分页插件,可以为我们MyBatis的分页功能提供方便快捷的支持。而其中,startPage无疑是PageHelper详细中的重要方法之一。本文将针对age方法进行详细介绍,给出它的工作原理及实现细节。

一、实现原理

从最初看到age方法的形式可以看出,它是在Mapper类中提供的,我们通过调用它指定所需要的分页信息,包括当前页数,每页数据数量等,然后再通过SQL查询得到所需要的分页数据,最终将分页数据返回给用户。其中startPage方法被称为分页控制器,在MyBatis中,它将通过ThreadLocal方式储存用户指定的分页数据,并根据这些数据在查询方法执行时对SQL语句进行改写,以达到分页的目的。

在PageHelper中,startPage主要执行了以下几个工作

1.为当前线程储存用户指定的分页参数:Page(currentPage,pageSize);

2.使用Page构造一个Page对象,用于封装从数据库中查询出来的数据

3.计算出需要进行的SQL改写,例如:将“SELECT *

FROM table”改写成 “SELECT * FROM table WHERE

rownum >= ? AND rownum <= ?”

其中第一点相对比较简单,第二点和第三点的实现稍稍复杂。

二、PageHelper源码分析

1. ThreadLocal的储存

PageHelper使用ThreadLocal方式储存用户指定的分页参数,这种方式下,用户的分页参数只能在当前线程中使用,这样做的好处在于每个线程都可以使用自己的分页参数,防止参数混乱。具体实现如下:

``` public static void startPage(int pageNum,

int pageSize, boolean count){ //为当前线程的Page对象赋值 Page page = new

Page(pageNum,pageSize,count);

LOCAL_(page); } ```

通过这样的代码,我们可以看到page对象是以ThreadLocal的形式存储在LOCAL_PAGE变量中,即在当前线程中存储了一个Page对象。在MyBatis查询过程中,Page对象将在筛选器(Interceptor)中被读取到,并从中获得用户指定的分页信息。

2. MyBatis筛选器的改写

MyBatis的筛选器是MyBatis插件中的核心部分,它可以拦截MyBatis的执行过程并修改其执行逻辑,被PageHelper用来改写MyBatis查询逻辑。

PageHelper的筛选器类是PageInterceptor,它主要通过实现Interceptor接口来拦截MyBatis执行过程,并将用户指定的分页参数转化为SQL查询条件。具体代码实现如下:

``` public Object intercept(Invocation

invocation) throws Throwable { boolean

isSupportedStatement =

ortedStatement(get()); Object parameter =

s()[1];//查询参数 RowBounds

rowBounds = ((MappedStatement)

s()[0]).getRowBounds();

Page page = ();//获取当前线程的Page对象 if (isSupportedStatement && rowBounds

== DEFAULT_ROWBOUNDS && page != null &&

lag()) { //根据Page对象计算出分页查询条件并应用到sql语句中 String originalSql

= (String) s()[0]; //

START_PAGE也是PageHelper提供的常量,专门用于计算分

页参数 String newSql =

tePageSql(originalSql, page,

DIALECT); s()[0] =

buildNewMappedStatement(invocation, newSql,

parameter); } return d(); }

```

interceptor方法中最重要的一点就是生成分页查询条件,这部分代码被写在了tePageSql方法中。在每次分页查询时,MyBatis会在执行查询前首先调用PageInterceptor的interceptor方法,判断当前查询是否需要分页,并将当前线程的分页参数传给tePageSql()方法进行分页条件生成。

generatePageSql方法中使用了StartPageHelper和EndPageHelper两个内部类来计算当前分页条件。StartPageHelper类实现了如下功能:

``` public static String

generateQuerySql(String sql){ return

"SELECT * FROM (SELECT INNER_TABLE.*,ROWNUM AS RN

FROM (" + sql+ ") INNER_TABLE WHERE ROWNUM <= ?)

WHERE RN > ?"; } ```

这段代码的作用是将原始SELECT语句包裹成一个子查询,同时新增一个列表示当前行编号,通过这种方式获取

到所需要的分页数据。对于参数替换,EndPageHelper类的作用则很简单,只需要解析Page对象中的参数替换到查询语句中即可。

三、总结

在本文中,我们对age方法的实现原理进行了深入的剖析。从中我们可以看出,startPage方法是pageHelper插件的核心部分,它通过ThreadLocal技术储存用户指定的分页参数,并通过MyBatis的筛选器改写SQL查询语句,最终实现了MyBatis分页查询的功能。

同时,我们也可以看到PageHelper提供的分页查询方法除了startPage之外,还有很多值得我们学习的地方,这些内容可能会在后续的文章中进行进一步的讲解。


本文标签: 查询 参数 用户 方法 进行