分页是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. 每月最后一周的周六晚上21:00执行任务-crontab

    0 21 * * 6 /bin/sh /root/time.sh #“6”代表周六 时间判断脚本如下: #!/bin/bash if [ "$(date -d "+7 days&q ...

  2. vs [失败]未能找到文件

    用文本文件打开csproj 文件.将里面的不需要文件删除; 或者在工程里面先将其移出工程.然后再删除;

  3. Node.js web发布到AWS ubuntu 之后,关闭Putty,Node 项目也随之关闭的解决办法

    最近公司把BlockChain和对应的Node Web都发布到了AWS 的ubuntu 系统上. 但是遇到了一个问题,每次启动 Node Web之后,关闭Putty,Node Web也随之关闭. 由于 ...

  4. boost asio 学习(九) boost::asio 网络封装

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...

  5. 【Mybatis】MyBatis快速入门(一)

    Mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...

  6. LOJ-10102(桥的判断)

    题目链接:传送门 思路:找桥就行了,条件是num[v]<low[u],pre!=v; #include<iostream> #include<cstdio> #inclu ...

  7. vue路由跳转到指定页面

    1.this.$router.push({name:'Home'}) 2.this.$router.push({path:'/view'}) 3.this.$router.replace({name: ...

  8. python模块:time

    # encoding: utf-8 # module time # from (built-in) # by generator 1.145 """ This modul ...

  9. SQL SERVER占用CPU过高优化

    操作系统是Windows2008R2 ,数据库是SQL2014 64位. 近阶段服务器出现过几次死机,管理员反馈机器内存使用率100%导致机器卡死.于是做了个监测服务器的软件实时记录CPU数据,几日观 ...

  10. js-闪烁的文字

    <!DOCTYPE html><html>    <head lang="en">        <meta charset=" ...