Mybatis分页插件2.0版本号公布
项目地址:http://git.oschina.net/free/Mybatis_PageHelper
软件介绍:http://www.oschina.net/p/mybatis_pagehelper
分页插件演示样例: http://blog.csdn.net/isea533/article/details/24700339
v2.0更新内容:
- 支持Mybatis缓存。count和分页同一时候支持(二者同步)
- 改动拦截器签名。拦截Executor,签名例如以下:
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) - 将Page类移到外面,方便调用
有位朋友留言说插件不支持缓存。在使用缓存的情况下无法正常执行。
这个问题确实存在,由于缓存是CachingExecutor在v1.0版本号中的拦截器之前进行的,也就是说,当查询结果被缓存后。使用缓存的时候是进不到分页插件中的。并且分页插件无法取得返回的结果。因而不能正常执行,既然找到了原因,并且Executor也能够被拦截。我就在想是否能直接拦截Executor并且支持缓存。
通过查看源代码以及调试。找到一种可行的方法。而且经过多项測试到最后完毕,共计4小时。我測试的内容有缓存/不缓存两种情况,以及返回为resultType/resultMap两种情况,共计4种情况下的使用情况。
測试仍然不算全面,所以我希望使用该插件的各位朋友遇到问题能及时反馈。
这次更新和前一个版本号的实现方法毫无关联。并且也从来没人这么做过。所以有问题请及时反馈,以下说说详细的实现方法。
首先拦截器签名变了:
1 |
@Intercepts(@Signature(typeclass, |
2 |
method"query", |
3 |
argsclass, |
4 |
Object.class, |
5 |
RowBounds.class, |
6 |
ResultHandler.class})) |
查看完整代码请点击这里,以下讲一些实现的细节:
1 |
List<SqlNode>"sqlSource.rootSqlNode.contents"); |
这段代码获取了SqlNode集合,Mybatis要运行的Sql从通过这个集合拼出来了,在第一个版本号的中的BoundSql就是通过contents中的内容生成的, 所以这样的分页方式绝对是意想不到的。获取这个对象后,做了例如以下处理:
1 |
//求count |
2 |
contents.add(0, new TextSqlNode("select)); |
3 |
contents.add(new TextSqlNode(")")); |
往第一行插入了求count的sql,最后一行加了一个“)”,通过头尾加入的这两个,就让这一个正常的sql语句变成了一个求count的sql,以下这一句代码:
1 |
Class<?>"resultMaps[0].type"); |
这一句代码的作用是先把正常的返回值类型保存,然后做了例如以下改动:
1 |
msObject.setValue("resultMaps[0].type", int.class); |
将返回值改为int类型。用于接收返回的count总数,另一句非常重要的代码:
1 |
List<ResultMapping>"resultMaps[0].resultMappings"); |
这里也是先把resultMappings备份,这个值在使用resultMap的情况会对返回结果造成干扰。所以这里先备份,然后用一个空的list去取代:
1 |
msObject.setValue("resultMaps[0].resultMappings", |
然后就去运行这个改动后的sql:
01 |
//查询总数 |
02 |
Objectnull; |
03 |
try { |
04 |
result |
05 |
int totalCount0).toString()); |
06 |
page.setTotal(totalCount); |
07 |
int totalPage0)0 : 1); |
08 |
page.setPages(totalPage); |
09 |
} finally { |
10 |
//清理count |
11 |
contents.remove(0); |
12 |
contents.remove(contents.size()1); |
13 |
//恢复类型 |
14 |
msObject.setValue("resultMaps[0].type", |
15 |
msObject.setValue("resultMaps[0].resultMappings", |
16 |
} |
由于这里运行了result = invocation.proceed()方法,所以在开启缓存的情况下,该sql也会被缓存,这里将结果totalCount保存到Page,然后在finally中运行了清理sql的方法和恢复类型的方法。这样就又变成了原来的sql。
这里通过运行过程中的截图来看一下实际效果:
添加头尾的count语句
运行的sql
后面使用同样的原理改动为分页SQL:
1 |
//分页sql |
2 |
contents.add(0, new TextSqlNode("select)); |
3 |
StringBuildernew StringBuilder(200); |
4 |
pageSql.append(").append(page.getEndRow()); |
5 |
pageSql.append(")).append(page.getStartRow()); |
6 |
contents.add(new TextSqlNode(pageSql.toString())); |
运行过程图:
添加头尾的分页sql
运行的sql
最后运行改动后的sql,保存处理结果:
01 |
//将运行权交给下一个拦截器 |
02 |
try { |
03 |
result |
04 |
} finally { |
05 |
//清理分页sql |
06 |
contents.remove(0); |
07 |
contents.remove(contents.size()1); |
08 |
} |
09 |
//得到处理结果 |
10 |
page.setResult((List) |
11 |
//返回结果 |
12 |
return result; |
这里仍然不能忘记在finally中清理sql。
通过这样的方法,全然使用了Mybatis的内容来操作,并且能够支持缓存。缓存对求count语句来说效果更明显,由于你查看下一页内容的时候不会反复运行count。会使用缓存。并且分页sql和count sql是同步缓存的。所以不用操心数据不一致的情况。并且这样的分页方式不影响原方法的单独运行(不分页)。
假设对你有帮助,或者有什么建议欢迎留言!
转载请注明原文地址和作者。
Mybatis分页插件2.0版本号公布的更多相关文章
- Mybatis分页插件
mybatis配置 <!-- mybatis分页插件 --> <bean id="pagehelper" class="com.github.pageh ...
- Mybatis分页插件PageHelper的配置和使用方法
Mybatis分页插件PageHelper的配置和使用方法 前言 在web开发过程中涉及到表格时,例如dataTable,就会产生分页的需求,通常我们将分页方式分为两种:前端分页和后端分页. 前端分 ...
- Mybatis分页插件PageHelper使用
一. Mybatis分页插件PageHelper使用 1.不使用插件如何分页: 使用mybatis实现: 1)接口: List<Student> selectStudent(Map< ...
- SSM 使用 mybatis 分页插件 pagehepler 实现分页
使用分页插件的原因,简化了sql代码的写法,实现较好的物理分页,比写一段完整的分页sql代码,也能减少了误差性. Mybatis分页插件 demo 项目地址:https://gitee.com/fre ...
- Mybatis学习---Mybatis分页插件 - PageHelper
1. Mybatis分页插件 - PageHelper说明 如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件. 该插件目前支持Oracle,Mysql,MariaDB,S ...
- Mybatis分页插件PageHelper的实现
Mybatis分页插件PageHelper的实现 前言 分页这个概念在做web网站的时候很多都会碰到 说它简单吧 其实也简单 小型的网站,完全可以自己写一个,首先查出数据库总条数,然后按照分页大小分为 ...
- 基于Mybatis分页插件PageHelper
基于Mybatis分页插件PageHelper 1.分页插件使用 1.POM依赖 PageHelper的依赖如下.需要新的版本可以去maven上自行选择 <!-- PageHelper 插件分页 ...
- Mybatis分页插件-PageHelper的使用
转载:http://blog.csdn.net/u012728960/article/details/50791343 Mybatis分页插件-PageHelper的使用 怎样配置mybatis这里就 ...
- (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示
http://blog.csdn.net/yerenyuan_pku/article/details/72774381 上文我们实现了展示后台页面的功能,而本文我们实现的主要功能是展示商品列表,大家要 ...
随机推荐
- luogu2437 蜜蜂路线
题目大意 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房M开始爬到蜂房N,M<N,有多少种爬行路线?M,N<=1000 题解 看到M ...
- luogu1771 方程的解
题目大意 对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数),x,k是给定的数.我们要求的是这个不定 ...
- JS函数种类详解
1. 普通函数1.1 示例 1 2 3 function ShowName(name) { alert(name); } 1.2 Js中同名函数的覆盖 在Js中函数是没有重载,定义相同函数名.不同 ...
- shp系列(六)——利用C++进行Dbf文件的写(创建)
上一篇介绍了shp文件的创建,接下来介绍dbf的创建. 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 1.Dbf头文件的创建 Dbf头文件的结构 ...
- nRF52832添加微信硬件接入服务AirSync
开发环境 SDK版本:nRF5_SDK_15.0.0 芯片:nRF52832-QFAA OS: FreeRTOS 10.0.0 测试APP:AirSyncDebugger https://iot.w ...
- ios UISegmentedControl的使用简介
初始化UISegmentedControl NSArray *arr = [[NSArray alloc]initWithObjects:@"轻拍",@"长按" ...
- java selenium手动最大化chrome浏览器的方法
package my_automation; import java.awt.Dimension; import org.openqa.selenium.Capabilities; import or ...
- C# How to convert MessageBodyStream to MemoryStream?
通过WCF服务从数据库取文档数据时,返回的是Stream对象,在DevExpress的PDFViewer显示时,用PDFViewer.LoadDocunent(Stream stream);方法时,报 ...
- 【正则表达式】从json数组中抽取id列表
有如下数组,要从中取出id: "[\"3812662409\",\"3812633637\",\"3812627686\",\&q ...
- javascript中in用法介绍
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...