自定义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);

原文地址:https://www.cnblogs.com/mayouyou/p/13284139.html