若依系统分页工具学习-PageHelper篇八

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

在《若依系统分页工具学习-PageHelper篇七》中,我们已经知晓了Dialect至MySqlDialect的类继承结果,如下:

Dialect -> AbstractDialect -> AbstractHelperDialect -> MySqlDialect

并且已经知道了方法beforePage方法定义与Dialect,实现在AbstractHelperDialect中,判断SQL语句是否需要分页。

其中涉及到一个Page对象,beforePage中涉及到了Page对象是如何获取的呢?今天我们来看一下。

Page的获取

我们来看Page对象是如何在beforePage获取的:

1
java复制代码Page page = getLocalPage();

我们再来看getLocalPage方法:

1
2
3
4
5
6
7
8
java复制代码    /**
* 获取分页参数
* @param <T>
* @return
*/
public <T> Page<T> getLocalPage() {
return PageHelper.getLocalPage();
}

恩,继续深入查看:

1
2
3
4
5
6
7
java复制代码    /**
* 获取 Page 参数
* @return
*/
public static <T> Page<T> getLocalPage() {
return LOCAL_PAGE.get();
}

这里的LOCAL_PAGE是如何定义的呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码/**
* 基础分页方法
* @author liuzh
*/
public abstract class PageMethod {
protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<Page>();

/**
* 设置 Page 参数
* @param page
*/
protected static void setLocalPage(Page page) {
LOCAL_PAGE.set(page);
}
}

这里的LOCAL_PAGE是不是有些熟悉呢?

在文章《若依系统分页工具学习-PageHelper篇二》中,通过Controller中的方法startPage的调用层次中,调用了PageMethod中的startPage方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
java复制代码 public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
Page<E> page = new Page<E>(pageNum, pageSize, count);
page.setReasonable(reasonable);
page.setPageSizeZero(pageSizeZero);
//当已经执行过orderBy的时候
Page<E> oldPage = getLocalPage();
if (oldPage != null && oldPage.isOrderByOnly()) {
page.setOrderBy(oldPage.getOrderBy());
}
setLocalPage(page);
return page;
}

/**
* 设置 Page 参数
*
* @param page
*/
protected static void setLocalPage(Page page) {
LOCAL_PAGE.set(page);
}

如此便通过一个线程内部变量ThreadLocal<Page>传过来了参数。

恩,这种传参方式没有深入理解的功力干不出来啊!反正我是不敢用~~

我们接着看beforePage方法中判断逻辑:

1
2
3
4
5
6
7
8
java复制代码@Override
public boolean beforePage(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {
Page page = getLocalPage();
if (page.isOrderByOnly() || page.getPageSize() > 0) {
return true;
}
return false;
}

如果分页参数的orderByOnly为true或者有pageSize大于0,则执行分页。

我们返回去看pageQuery方法中的逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
java复制代码    /**
* 分页查询
*/
public static <E> List<E> pageQuery(Dialect dialect, Executor executor, MappedStatement ms, Object parameter,
RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql, CacheKey cacheKey) throws SQLException {
//判断是否需要进行分页查询
if (dialect.beforePage(ms, parameter, rowBounds)) {
//生成分页的缓存 key
CacheKey pageKey = cacheKey;
//处理参数对象
parameter = dialect.processParameterObject(ms, parameter, boundSql, pageKey);
....

这里缓存我们暂时不说。

看下一句调用的dialect方法:processParameterObject,注释为:“处理参数对象”,这个方法又在哪个类结构层次中呢?

最后发现它和beforePage一样,位于类AbstractHelperDialect中。

为了尽快查看SQL修改的具体位置我们暂时不对这个processParameterObject方法深入了解。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%