• Mybatis Plugin(拦截器)的开发


    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()
     1 FirstIntercepter=====>setProperties
     2 FirstIntercepter====>pluginorg.apache.ibatis.executor.CachingExecutor@64485a47
     3 FirstIntercepter====>pluginorg.apache.ibatis.scripting.defaults.DefaultParameterHandler@2f0a87b3
     4 FirstIntercepter====>pluginorg.apache.ibatis.executor.resultset.DefaultResultSetHandler@4fcd19b3
     5 FirstIntercepter====>pluginorg.apache.ibatis.executor.statement.RoutingStatementHandler@2fd66ad3
     6 DEBUG 09-05 11:56:24,696 ==> Preparing: select * from employee where id=? (BaseJdbcLogger.java:159)
     7 FirstIntercepter:===>intercept
     8 DEBUG 09-05 11:56:24,722 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
     9 DEBUG 09-05 11:56:24,739 <== Total: 1 (BaseJdbcLogger.java:159)
    10 Employee [id=1, lastName=tom, gender=1, email=asd@qq.com, depid=null]
     
      1. 给你的拦截器签名:
     1 /**
     2 * 完成插件签名:
     3 * 告诉MyBatis当前插件用来拦截哪个对象的哪个方法
     4 * type:要拦截的四大类型
     5 * method:拦截那个方法
     6 * args:这个方法的入参
     7 * */
     8 @Intercepts({
     9 @Signature(type=StatementHandler.class,
    10 method="parameterize",
    11 args=java.sql.Statement.class
    12 )
    13 })
    14 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
     1 MySecondIntercepter====>setProperties:{param1=root}
     2 FirstIntercepter====>pluginorg.apache.ibatis.executor.CachingExecutor@64485a47
     3 MySecondIntercepter====>plugin:org.apache.ibatis.executor.CachingExecutor@64485a47
     4 FirstIntercepter====>pluginorg.apache.ibatis.scripting.defaults.DefaultParameterHandler@2f0a87b3
     5 MySecondIntercepter====>plugin:org.apache.ibatis.scripting.defaults.DefaultParameterHandler@2f0a87b3
     6 FirstIntercepter====>pluginorg.apache.ibatis.executor.resultset.DefaultResultSetHandler@4fcd19b3
     7 MySecondIntercepter====>plugin:org.apache.ibatis.executor.resultset.DefaultResultSetHandler@4fcd19b3
     8 FirstIntercepter====>pluginorg.apache.ibatis.executor.statement.RoutingStatementHandler@2fd66ad3
     9 MySecondIntercepter====>plugin:org.apache.ibatis.executor.statement.RoutingStatementHandler@2fd66ad3
    10 DEBUG 09-05 12:07:01,928 ==> Preparing: select * from employee where id=? (BaseJdbcLogger.java:159)
    11 MySecondIntercepter====>intercept:public abstract void org.apache.ibatis.executor.statement.StatementHandler.parameterize(java.sql.Statement) throws java.sql.SQLException
    12 FirstIntercepter:===>intercept
    13 DEBUG 09-05 12:07:01,954 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
    14 DEBUG 09-05 12:07:01,968 <== Total: 1 (BaseJdbcLogger.java:159)
    15 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中所以注意签名
    • 1 @Intercepts({
      2 @Signature(type=StatementHandler.class,
      3 method="parameterize",
      4 args=java.sql.Statement.class
      5 )
      6 })
      业务逻辑intercept方法中
     1 /**
     2 * 1:业务逻辑处理的方法:
     3 */
     4 @Override
     5 public Object intercept(Invocation invocation) throws Throwable {
     6 //在这里可以进行业务逻辑修改
     7 System.out.println("FirstIntercepter:===>intercept"+invocation.getMethod());
     8  
     9 MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget());
    10 //拿到target的元数据 StatementHandler==>ParameterHandler===>
    11 //DefaultParameterHandler==>>parameterObject
    12 Object value = metaObject.getValue("parameterHandler.parameterObject");
    13 System.out.println("sql "+value.toString());
    14 //修改完sql语句要用的参数
    15 metaObject.setValue("parameterHandler.parameterObject", 2);
    16 Object object = invocation.proceed();
    17 return object;
    18 }
     
    • 打印log,
      • 可以看到原来入参为1,现在经过拦截器修改入参为2
    1 DEBUG 09-05 12:36:23,387 ==> Preparing: select * from employee where id=? (BaseJdbcLogger.java:159)
    2 MySecondIntercepter====>intercept:public abstract void org.apache.ibatis.executor.statement.StatementHandler.parameterize(java.sql.Statement) throws java.sql.SQLException
    3 FirstIntercepter:===>interceptpublic abstract void org.apache.ibatis.executor.statement.StatementHandler.parameterize(java.sql.Statement) throws java.sql.SQLException
    4 sql 1
    5 DEBUG 09-05 12:36:23,418 ==> Parameters: 2(Integer) (BaseJdbcLogger.java:159)
    6 DEBUG 09-05 12:36:23,432 <== Total: 1 (BaseJdbcLogger.java:159)
    7 Employee [id=2, lastName=cat, gender=0, email=qwe@qq.com, depid=null]
     
  • 相关阅读:
    Linq技术四:动态Linq技术 -- Linq.Expressions
    74HC595的中文资料
    MessageDigest简单介绍
    gpu显存(全局内存)在使用时数据对齐的问题
    走进windows编程的世界-----windows进程
    Matlab画图-非常具体,非常全面
    php实现 合并表记录(需求是最好的老师)
    php实现求一个数的质数因子
    php课程 4-16 数组自定义函数(php数组->桶)
    jquery-3 jquery选择器
  • 原文地址:https://www.cnblogs.com/dgwblog/p/9591499.html
Copyright © 2020-2023  润新知