1.Plugin
 
MyBatis 允许使用插件来拦截的方法调用包括:
• Executor (update, query, flushStatements, commit, rollback,
getTransaction, close, isClosed)
• ParameterHandler (getParameterObject, setParameters)
• ResultSetHandler (handleResultSets, handleOutputParameters)
• StatementHandler (prepare, parameterize, batch, update, query)
注意;可以通过插件拦截到这四个对象,修改参数等操作:
 
你必须要知道的类:
  1. org.apache.ibatis.plugin.Plugin
  2. org.apache.ibatis.reflection.SystemMetaObject
 
2.使用步骤
    1. 实现 Interceptor 接口
      1. 三个方法执行顺序
        1. setProperties()
        2. plugin()
        3. intercept()
 FirstIntercepter=====>setProperties
FirstIntercepter====>pluginorg.apache.ibatis.executor.CachingExecutor@64485a47
FirstIntercepter====>pluginorg.apache.ibatis.scripting.defaults.DefaultParameterHandler@2f0a87b3
FirstIntercepter====>pluginorg.apache.ibatis.executor.resultset.DefaultResultSetHandler@4fcd19b3
FirstIntercepter====>pluginorg.apache.ibatis.executor.statement.RoutingStatementHandler@2fd66ad3
DEBUG 09-05 11:56:24,696 ==> Preparing: select * from employee where id=? (BaseJdbcLogger.java:159)
FirstIntercepter:===>intercept
DEBUG 09-05 11:56:24,722 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-05 11:56:24,739 <== Total: 1 (BaseJdbcLogger.java:159)
Employee [id=1, lastName=tom, gender=1, email=asd@qq.com, depid=null]
 
    1. 给你的拦截器签名:
 /**
* 完成插件签名:
* 告诉MyBatis当前插件用来拦截哪个对象的哪个方法
* type:要拦截的四大类型
* method:拦截那个方法
* args:这个方法的入参
* */
@Intercepts({
@Signature(type=StatementHandler.class,
method="parameterize",
args=java.sql.Statement.class
)
})
public class FirstIntercepter implements Interceptor
 
    1. mybatis-cfg.xml中配置插件
      1. 这里注意配置plugins的标签顺序,以免出错,在environments上面
<!-- plugins 插件的配置 实际上是使用:intercepter原理代理的 -->
<plugins>
<plugin interceptor="mybatis.intercepter.FirstIntercepter">
<property name="param1" value="root"/>
<property name="param2" value="root"/>
</plugin>
</plugins>
 
3.多个插件的执行
  1. 、多个插件依次生成目标对象的代理对象,层层包裹,先声明的先包裹;形成代理链
  2. 、可以理解为:初始化执行
  3. 执行log
  4. FirstIntercepter=====>setProperties
 MySecondIntercepter====>setProperties:{param1=root}
FirstIntercepter====>pluginorg.apache.ibatis.executor.CachingExecutor@64485a47
MySecondIntercepter====>plugin:org.apache.ibatis.executor.CachingExecutor@64485a47
FirstIntercepter====>pluginorg.apache.ibatis.scripting.defaults.DefaultParameterHandler@2f0a87b3
MySecondIntercepter====>plugin:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@2f0a87b3
FirstIntercepter====>pluginorg.apache.ibatis.executor.resultset.DefaultResultSetHandler@4fcd19b3
MySecondIntercepter====>plugin:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4fcd19b3
FirstIntercepter====>pluginorg.apache.ibatis.executor.statement.RoutingStatementHandler@2fd66ad3
MySecondIntercepter====>plugin:org.apache.ibatis.executor.statement.RoutingStatementHandler@2fd66ad3
DEBUG 09-05 12:07:01,928 ==> Preparing: select * from employee where id=? (BaseJdbcLogger.java:159)
MySecondIntercepter====>intercept:public abstract void org.apache.ibatis.executor.statement.StatementHandler.parameterize(java.sql.Statement) throws java.sql.SQLException
FirstIntercepter:===>intercept
DEBUG 09-05 12:07:01,954 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-05 12:07:01,968 <== Total: 1 (BaseJdbcLogger.java:159)
Employee [id=1, lastName=tom, gender=1, email=asd@qq.com, depid=null]
 
4.实现拦截修改参数
 
  • sql
<!-- Employee getSelectEmp(Integer id); -->
<select id="getSelectEmp" parameterType="java.lang.Integer"
resultType="mybatis.bean.Employee">
select * from employee where id=#{id}
</select>
  • 这里我们拦截id:
由于ibatis中参数的声明存在与 StatementHandler中所以注意签名
  •  @Intercepts({
    @Signature(type=StatementHandler.class,
    method="parameterize",
    args=java.sql.Statement.class
    )
    })

    业务逻辑intercept方法中

 /**
* 1:业务逻辑处理的方法:
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
//在这里可以进行业务逻辑修改
System.out.println("FirstIntercepter:===>intercept"+invocation.getMethod()); MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget());
//拿到target的元数据 StatementHandler==>ParameterHandler===>
//DefaultParameterHandler==>>parameterObject
Object value = metaObject.getValue("parameterHandler.parameterObject");
System.out.println("sql "+value.toString());
//修改完sql语句要用的参数
metaObject.setValue("parameterHandler.parameterObject", 2);
Object object = invocation.proceed();
return object;
}
 
  • 打印log,
    • 可以看到原来入参为1,现在经过拦截器修改入参为2
 DEBUG 09-05 12:36:23,387 ==> Preparing: select * from employee where id=? (BaseJdbcLogger.java:159)
MySecondIntercepter====>intercept:public abstract void org.apache.ibatis.executor.statement.StatementHandler.parameterize(java.sql.Statement) throws java.sql.SQLException
FirstIntercepter:===>interceptpublic abstract void org.apache.ibatis.executor.statement.StatementHandler.parameterize(java.sql.Statement) throws java.sql.SQLException
sql 1
DEBUG 09-05 12:36:23,418 ==> Parameters: 2(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-05 12:36:23,432 <== Total: 1 (BaseJdbcLogger.java:159)
Employee [id=2, lastName=cat, gender=0, email=qwe@qq.com, depid=null]
 

Mybatis Plugin(拦截器)的开发的更多相关文章

  1. Mybatis Interceptor 拦截器原理 源码分析

    Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...

  2. mybatis Interceptor拦截器代码详解

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

  3. Mybatis之拦截器原理(jdk动态代理优化版本)

    在介绍Mybatis拦截器代码之前,我们先研究下jdk自带的动态代理及优化 其实动态代理也是一种设计模式...优于静态代理,同时动态代理我知道的有两种,一种是面向接口的jdk的代理,第二种是基于第三方 ...

  4. Mybatis利用拦截器做统一分页

    mybatis利用拦截器做统一分页 查询传递Page参数,或者传递继承Page的对象参数.拦截器查询记录之后,通过改造查询sql获取总记录数.赋值Page对象,返回. 示例项目:https://git ...

  5. mybatis定义拦截器

    applicationContext.xml <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlS ...

  6. MyBatis实现拦截器分页功能

    1.原理 在mybatis使用拦截器(interceptor),截获所执行方法的sql语句与参数. (1)修改sql的查询结果:将原sql改为查询count(*) 也就是条数 (2)将语句sql进行拼 ...

  7. mybatis自定义插件(拦截器)开发详解

    mybatis插件(准确的说应该是around拦截器,因为接口名是interceptor,而且invocation.proceed要自己调用,配置中叫插件)功能非常强大,可以让我们无侵入式的对SQL的 ...

  8. Mybatis自定义拦截器与插件开发

    在Spring中我们经常会使用到拦截器,在登录验证.日志记录.性能监控等场景中,通过使用拦截器允许我们在不改动业务代码的情况下,执行拦截器的方法来增强现有的逻辑.在mybatis中,同样也有这样的业务 ...

  9. MyBatis原理-拦截器

    一.MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,M ...

  10. mybatis - 基于拦截器修改执行语句中的ResultMap映射关系

    拦截器介绍 mybatis提供了@Intercepts注解允许开发者对mybatis的执行器Executor进行拦截. Executor接口方法主要有update.query.commit.rollb ...

随机推荐

  1. Kafka0.7运行时报错 kafka/javaapi/consumer/ConsumerConnector : Unsupported major.minor version 51.0 解决

    目前中央库中 org.apache.kafka 是用jdk1.7编译的, 故跑在1.6的jvm中会报错 解决方案: 1. 下载kafka源码, 本地sbt进行install, 编译前 java -ve ...

  2. P1880 [NOI1995]石子合并[区间dp+四边形不等式优化]

    P1880 [NOI1995]石子合并 丢个地址就跑(关于四边形不等式复杂度是n方的证明) 嗯所以这题利用决策的单调性来减少k断点的枚举次数.具体看lyd书.这部分很生疏,但是我还是选择先不管了. # ...

  3. JZOJ 1667【AHOI2009】中国象棋——dp

    题目:https://jzoj.net/senior/#main/show/1667 只注重0.1.2的列有多少个,不注重它们的位置,就能记录了. #include<iostream> # ...

  4. RT-Thread OS的启动流程

    1.RT进入main之前, SystemInit函数初始化时钟. 2.main函数位于startup.c文件中.进行两个工作 系统开始前,rt_hw_interrupt_disable关闭所有中断. ...

  5. javascript中原型链存在的问题

    我们知道使用原型链实现继承是一个goodway:)看个原型链继承的例子. function A () { this.abc = 44; } A.prototype.getAbc = function ...

  6. java基础之框架篇(1)

    框架基础反射:反射是Java开发的一类动态相关机制.因为本身Java语言并不是一款动态语言,如果我们想要得到程序动态的效果,因此便引入了反射机制这一概念. 问题:Java中创建实例化对象有哪些方式? ...

  7. reservoir sampling / random shuffle

    randomly choose a sample of k items from a list S containing n elements, the algorithm may be online ...

  8. 在Elasticsearch6.X中如何实现去重

    1.前言 Elasticsearch有没有类似mysql的distinct的去重功能呢? 1)如何去重计数? 类似mysql: select distinct(count(1)) from my_ta ...

  9. 编译portmap和nfs-utils

    编译portmap和nfs-utils 为了在播放机上实现NFS服务器的功能,我们已经在uClibc中打开了完整RPC支持,并且在新编译的内核中打开了NFS服务器支持.此外还有两个软件包也是提供NFS ...

  10. ASP.NET MVC (Umbraco)中如何设置网站超时自动退出

    原文章请参考  https://edgewebware.com/2014/06/automatically-log-out-members-send-login-page-umbraco/ 在网站开发 ...