分页是WEB程序中常见的功能,mybatis分页实现与hibernate不同,相比hibernate,mybatis实现分页更为麻烦。mybatis实现分页需要自己编写(非逻辑分页RowBounds),以mysql为例,使用分页时需要自己在mapper中的sql语句中添加LIMIT #{xx},#{xx}。这种方式不具备可重用性与可拓展性。

  mybatis提供了plugins,plugins实现了拦截器的功能。它可以拦截指定类中的方法,当指定的方法被执行时,mybatis就会自动拦截并完成相应逻辑。通过mybatis的plugins,就可以实现自动分页功能。

  实现分析:拦截查询语句,判断该查询语句是否需要添加分页,修改原来的sql语句,查询得到的总记录数

  具体源码在https://github.com/yuen666/mybatis-pagination

简要思路

  编写Interceptor,拦截StatementHandler中的prapare方法,在mybatis中,执行的是RoutingStatementHandler实现类。该类使用代理的方式来调用BaseStatementHandler。

  

  在每次使用查询语句时,都会调用RoutingStatementHandler.prepare(...),该方法的实现如下:

  

  它调用了delegate的prepare,实现类为BaseStatementHandler,源码如下:

  

  由于每次查询都调用该prepare方法,故可以对RoutingStatementHandler的prepare进行拦截。该方法中拥有connection对象,通过connection对象也可以连接数据库查询总记录数,比较方便。

  关于sql语句的修改。在delegate中,即BaseStatementHandler中,拥有如下几个域:

  

  其中,boundSql中包含了sql语句(boundSql.sql),由于是protected类型,所以可以采用反射的方式获取原sql语句并设置新sql语句。

  总结下:

  1. 拦截StatementHandler的prepare方法
  2. 通过反射获取delegate.boundSql.sql修改并设置
  3. 获取参数connection并查询中记录数

关于反射

  mybaits提供了MetaObject类,该类对反射进行封装。可以通过该类快速的实现获取与设置delegate.boundSql.sql。

private Object getValue(StatementHandler statementHandler, String exp) {
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
return metaObject.getValue(exp);
}
private void setValue(StatementHandler statementHandler, String exp, Object obj) {
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
metaObject.setValue(exp, obj);
}

  其中的exp为OGNL表达式。

MyBatis 分页之拦截器实现的更多相关文章

  1. MyBatis功能点二:MyBatis提供的拦截器平台

    前面关于MyBatis功能点二plugin已经介绍了一些应用及其实现的底层代码,本文总结MyBatis提供的拦截器平台框架体系. 通过MyBatis功能点二:从责任链设计模式的角度理解插件实现技术 - ...

  2. Mybatis中的拦截器

    作者:moshenglv的专栏 拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法. ...

  3. Mybatis自定义SQL拦截器

    本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...

  4. MyBatis空where拦截器

    最近项目中出现了至少两次因为Mybatis的动态where条件不满足导致实际sql语句的where条件为空,进而查询全表,当数据量比较大的时候,导致OOM的情况. 如何禁止这种情况,个人觉得三种措施: ...

  5. Mybatis Plugin(拦截器)的开发

    1.Plugin   MyBatis 允许使用插件来拦截的方法调用包括: • Executor (update, query, flushStatements, commit, rollback, g ...

  6. Mybatis那些事-拦截器(Plugin+Interceptor)

    作者:yhjyumi的专栏 数据权限实现(Mybatis拦截器+JSqlParser) Mybatis的拦截器实现机制,使用的是JDK的InvocationHandler. 当我们调用Paramete ...

  7. mybatis:SQL拦截器

    打印执行的SQL语句 import java.sql.Connection; import java.text.DateFormat; import java.util.Date; import ja ...

  8. MyBatis 插件之拦截器(Interceptor)

    参考 https://blog.csdn.net/weixin_39494923/article/details/91534658 //项目实际使用  就是在你进行数据库操作时,进行数据的第二次封装 ...

  9. 数据权限管理中心 - 基于mybatis拦截器实现

    数据权限管理中心 由于公司大部分项目都是使用mybatis,也是使用mybatis的拦截器进行分页处理,所以技术上也直接选择从拦截器入手 需求场景 第一种场景:行级数据处理 原sql: select ...

随机推荐

  1. 《JAVA程序设计》第四周总结

    第四周作业总结 学习内容: 1.根据教材视频学习第五章:子类和继承 2.调试代码和解决问题 3.上周错题 4.代码托管 知识总结 子类:在类的声明中,通过使用关键字extends来定义一个类的子类. ...

  2. 数据库mysql之慢查询优化

    今天项目遇到一个问题:就是在公司test环境中执行sql查询语句很快,也就几百毫秒,但是放到sit环境中测试就要延迟至少1分钟左右. 网上找了很多原因,大多数都是说索引问题,我看了索引没问题,又重新建 ...

  3. zeromq学习记录(五)vc下多线程

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  4. Office365 Manager Plus之报表

    Office365 Manager Plus之报表 也许您刚刚开始使用Office 365,对它的各个组件还有很多疑问,如何快速掌握Office 365各种服务的用法?如何管理邮箱?如何监控邮件流量? ...

  5. 《Linux就该这么学》第二天课程

    秦时明月经典语录:很多人被命运安排,而我安排命运.——卫庄 今天介绍了VM 虚拟机的安装以及Linux系统的安装,还讲解了Linux内核 RPM:降低软件的安装难度 源代码+安装规则→将程序源代码与安 ...

  6. Codesmith怎么判断sqlserver数据库字段是不是标识自增字段

    Codesmith怎么判断sqlserver数据库字段是不是标识自增字段 使用ExtendedProperty扩展信息判断 CS_isIdentity:是否为标识符,不支持Access CS_isCo ...

  7. docker安装redis 指定配置文件且设置了密码

    ---------首先,所有docker的命令,都可以用 docker help 来查询,这个挺好的,我反正记不住辣么多命令呀.   1.直接pull 官方镜像吧.没啥说的,这样方便省事.如果你非要用 ...

  8. oracle utl_http 访问https类型

    https://oracle-base.com/articles/misc/utl_http-and-ssl http://blog.whitehorses.nl/2010/05/27/access- ...

  9. Mapreduce atop Apache Phoenix (ScanPlan 初探)

    利用Mapreduce/hive查询Phoenix数据时如何划分partition? PhoenixInputFormat的源码一看便知: public List<InputSplit> ...

  10. Elastic-search在linux上的安装

    今天是我装第四次 ES ,之前装好用了一段时间,后面莫名其妙爆炸了,炸出一堆异常... 安装环境: JDK1.8   centos    ElasticSearch-6.2.4 jdk1.8以上,所以 ...