我是靠谱客的博主 舒心吐司,这篇文章主要介绍使用com.github.pagehelper插件分页、count分析,现在分享给大家,希望可以做个参考。

pagehelper侵入研究

mybatis插件中有一个拦截器org.apache.ibatis.plugin.Interceptor,主要用于mybatis插件的植入。pagehelper的PageInterceptor实现了Interceptor,PageInterceptor在所有执行query操作时插入拦截。

PageInterceptor 分页器跳过分页
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//调用方法判断是否需要进行分页,如果不需要,直接返回结果 if (!dialect.skip(ms, parameter, rowBounds)) { ... } public boolean skip(MappedStatement ms, Object parameterObject, RowBounds rowBounds) { if(ms.getId().endsWith(MSUtils.COUNT)){ throw new RuntimeException("在系统中发现了多个分页插件,请检查系统配置!"); } //获取分页参数成功,则分页,获取失败,则跳过分页 Page page = pageParams.getPage(parameterObject, rowBounds); if (page == null) { return true; } else { //设置默认的 count 列 if(StringUtil.isEmpty(page.getCountColumn())){ page.setCountColumn(pageParams.getCountColumn()); } autoDialect.initDelegateDialect(ms); return false; } }

从skip方法可以看出,跳过分页的重点在pageParams.getPage。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//如果当前threadlocal中有page取当前threadlocal中的page Page page = PageHelper.getLocalPage(); if (page == null) { // 不人为修改时rowBounds = RowBounds.DEFAULT if (rowBounds != RowBounds.DEFAULT) { if (offsetAsPageNum) { page = new Page(rowBounds.getOffset(), rowBounds.getLimit(), rowBoundsWithCount); } else { page = new Page(new int[]{rowBounds.getOffset(), rowBounds.getLimit()}, rowBoundsWithCount); //offsetAsPageNum=false的时候,由于PageNum问题,不能使用reasonable,这里会强制为false page.setReasonable(false); } if(rowBounds instanceof PageRowBounds){ PageRowBounds pageRowBounds = (PageRowBounds)rowBounds; page.setCount(pageRowBounds.getCount() == null || pageRowBounds.getCount()); } //如果pagehelper.supportMethodsArguments 设置为true,也就是支持接口参数来传递分页参数 } else if(supportMethodsArguments){ try { page = PageObjectUtil.getPageFromObject(parameterObject, false); } catch (Exception e) { return null; } } if(page == null){ return null; } PageHelper.setLocalPage(page); }

从上面代码可以看出 如果没有修改rowBounds,并且没有设置pagehelper.supportMethodsArguments 属性为true,是不会走分页的,也就是直接skip掉了。但是通常我们希望接口来传递分页参数,会把pagehelper.supportMethodsArguments设置为true。所以会走page = PageObjectUtil.getPageFromObject(parameterObject, false)流程。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public static <T> Page<T> getPageFromObject(Object params, boolean required) { int pageNum; int pageSize; MetaObject paramsObject = null; if (params == null) { throw new PageException("无法获取分页查询参数!"); } if (hasRequest && requestClass.isAssignableFrom(params.getClass())) { try { paramsObject = MetaObjectUtil.forObject(getParameterMap.invoke(params, new Object[]{})); } catch (Exception e) { //忽略 } } else { paramsObject = MetaObjectUtil.forObject(params); } if (paramsObject == null) { throw new PageException("分页查询参数处理失败!"); } Object orderBy = getParamValue(paramsObject, "orderBy", false); boolean hasOrderBy = false; if (orderBy != null && orderBy.toString().length() > 0) { hasOrderBy = true; } try { Object _pageNum = getParamValue(paramsObject, "pageNum", required); Object _pageSize = getParamValue(paramsObject, "pageSize", required); if (_pageNum == null || _pageSize == null) { if(hasOrderBy){ Page page = new Page(); page.setOrderBy(orderBy.toString()); page.setOrderByOnly(true); return page; } return null; } pageNum = Integer.parseInt(String.valueOf(_pageNum)); pageSize = Integer.parseInt(String.valueOf(_pageSize)); } catch (NumberFormatException e) { throw new PageException("分页参数不是合法的数字类型!"); } Page page = new Page(pageNum, pageSize); //count查询 Object _count = getParamValue(paramsObject, "count", false); if (_count != null) { page.setCount(Boolean.valueOf(String.valueOf(_count))); } //排序 if (hasOrderBy) { page.setOrderBy(orderBy.toString()); } //分页合理化 Object reasonable = getParamValue(paramsObject, "reasonable", false); if (reasonable != null) { page.setReasonable(Boolean.valueOf(String.valueOf(reasonable))); } //查询全部 Object pageSizeZero = getParamValue(paramsObject, "pageSizeZero", false); if (pageSizeZero != null) { page.setPageSizeZero(Boolean.valueOf(String.valueOf(pageSizeZero))); } return page; }

从以上简单代码中我们可以发现,如果sql入参中存在 orderby或者同时存在pageNumpageSize那么page还是不等于null,即skip!=true

跳过查总数据

回到PageInterceptor的intercept方法,skip = true走分页流程时会判断是否需要进行 count 查询

复制代码
1
2
3
4
5
6
7
if (dialect.beforeCount(ms, parameter, rowBounds)) ... public boolean beforeCount(MappedStatement ms, Object parameterObject, RowBounds rowBounds) { Page page = getLocalPage(); return !page.isOrderByOnly() && page.isCount(); }

当page不是只orderBy时并且page.isCount()为true时,需要进行count查询,那么简单破坏Page就能达到跳过count查总数据需求。

最后

以上就是舒心吐司最近收集整理的关于使用com.github.pagehelper插件分页、count分析的全部内容,更多相关使用com内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部