自定义Mybatis拦截器和Plugin

Posted myyismyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义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})

  })

src\\org\\myy\\my\\interceptors\\MyInterceptor.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.配置

src\\conf.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")

 src\\org\\myy\\my\\interceptors\\MyInterceptor.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);

 

以上是关于自定义Mybatis拦截器和Plugin的主要内容,如果未能解决你的问题,请参考以下文章

自定义mybatis拦截器

MyBatis自定义Plugin

mybatis的相同拦截器—切面执行的顺序

mybatis拦截器(上)

mybatis-plugin的实现原理(源码分析)

mybatis-plugin的实现原理(源码分析)