• 自定义Mybatis拦截器和Plugin


    自定义插件:

      四个处理:StatementHandler  ParameterHandler  ResultSethandler  TypeHandler

      四大核心对象:StatementHandler  ParameterHandler  ResultSethandler  Executor

    四大核心对象:1.都涉及到了拦截器用于增强

           2.四大核心对象都包含了该增强操作

      自定义插件的编写逻辑:根据MyBatis规则编写一个拦截器,在拦截器内部加入加入自定义增强功能

      步骤:

      a.编写拦截器

      b.编写签名

      @Intercepts({

        @Signature(type = StatementHandler.class,method ="query",args = {Statement.class, ResultHandler.class})

      })

    srcorgmyymyinterceptorsMyInterceptor.java

    package org.myy.my.interceptors;
    
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.session.ResultHandler;
    
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Properties;
    
    //query(Statement var1, ResultHandler var2)
    @Intercepts({
            @Signature(type = StatementHandler.class,method ="query",args = {Statement.class, ResultHandler.class})
    })
    /*//query(Statement statement, ResultHandler resultHandler)
    @Intercepts({
    //        @Signature(type = StatementHandler.class , method ="query",args = {Statement.class, ResultHandler.class})
            @Signature(type = StatementHandler.class , method ="parameterize",args = {Statement.class})
    
    })*/
    public class MyInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("拦截方法...intercept...");
            Object proceed=invocation.proceed();//放行
            System.out.println(proceed);
            return proceed;
        }
    
        @Override
        public Object plugin(Object target) {//将拦截器中定义的增强功能和原来的核心对象合并起来称为最终的核心对象
            Object wrap = Plugin.wrap(target, this);
            return wrap;
        }
    
        @Override
        public void setProperties(Properties properties) {
            System.out.println("设置属性"+properties);//设置属性
        }
    }

      c.配置

    srcconf.xml

        <plugins>
            <plugin interceptor="org.myy.my.interceptors.MyInterceptor">
                <property name="name" value="zs"/>
                <property name="age" value="23"/>
            </plugin>
        </plugins>

     编写拦截器时,执行顺序和<plugins>配置顺序一致

    插件

      select * from student1->拦截器

      目标对象target的包装后的产物->metaObject.getValue("可以从target中获取")

      通过打印语句可知target=RoutingStatementHandler

    得出,metaObject.getValue("可以从RoutingStatementHandler中获取")

    继而,metaObject.getValue("可以从RoutingStatementHandler中获取:boundSql/parameterHandler")

    metaObject.getValue("parameterHandler.parameterObject")  ---XxxMapper.xml中的sql语句的参数值

    metaObject.getValue("parameterHandler.boundSql")  ---XxxMapper.xml中的sql语句

    只研究

      metaObject.getValue("parameterHandler.parameterObject")

     srcorgmyymyinterceptorsMyInterceptor.java

    package org.myy.my.interceptors;
    
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.reflection.SystemMetaObject;
    import org.apache.ibatis.session.ResultHandler;
    
    import java.sql.Statement;
    import java.util.Properties;
    
    //query(Statement var1, ResultHandler var2)
    @Intercepts({
            //@Signature(type = StatementHandler.class,method ="query",args = {Statement.class, ResultHandler.class})
            @Signature(type = StatementHandler.class,method ="parameterize",args = {Statement.class})
    
    })
    public class MyInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("拦截方法...intercept...");
    
    
            Object target = invocation.getTarget();//目标方法:select * from student1 where stuno=#{stuno}
            System.out.println("目标对象"+target);
            MetaObject metaObject = SystemMetaObject.forObject(target);
            //metaObject.getValue("参数..");
            Object value = metaObject.getValue("parameterHandler.parameterObject");
            System.out.println(value+"参数");
            metaObject.setValue("parameterHandler.parameterObject",1);//2->1
    
            value = metaObject.getValue("parameterHandler.parameterObject");
            System.out.println(value+"修改后参数");
    
            Object proceed=invocation.proceed();//放行
            System.out.println(proceed);
            return proceed;
        }
    
        @Override
        public Object plugin(Object target) {//将拦截器中定义的增强功能和原来的核心对象合并起来称为最终的核心对象
            Object wrap = Plugin.wrap(target, this);
            System.out.println("plugin...."+wrap);
            return wrap;
        }
    
        @Override
        public void setProperties(Properties properties) {
            //System.out.println("setProperties....");
            System.out.println("设置属性"+properties);//设置属性
        }
    }

     metaObject.setValue("parameterHandler.parameterObject",1);//2->1

     metaObject.setValue("parameterHandler.boundSql","select * from book...");

     metaObject.setValue("parameterHandler.boundSql.parameterObject",1);

  • 相关阅读:
    【scala语言入门】二、匿名函数
    【scala语言入门】 一、apply与unapply
    关于timeOut超时后是否会回滚的思考
    [算法]-插入排序
    【oenCV系列】 写视频
    【Opencv系列】
    Factory Method模式精解(C++版本)
    Template Method模式精解(C++版本)
    Adapter模式精解(C++版本)
    迭代器模式精解(C++版本)
  • 原文地址:https://www.cnblogs.com/mayouyou/p/13284139.html
Copyright © 2020-2023  润新知