Mybatis之插件开发之拦截器介绍

背景:mybatis插件(准确的说应该是around拦截器,因为接口名是interceptor,而且invocation.proceed要自己调用,配置中叫插件)功能非常强大,可以让我们无侵入式的对SQL的执行进行干涉,从SQL语句重写、参数注入、结果集返回等每个主要环节,典型的包括权限控制检查与注入、只读库映射、K/V翻译、动态改写SQL。

MyBatis默认支持对4大对象(Executor,StatementHandler,ParameterHandler,ResultSetHandler)上的方法执行拦截,具体支持的方法为:

Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed),主要用于sql重写。
ParameterHandler (getParameterObject, setParameters),用于参数处理。
ResultSetHandler (handleResultSets, handleOutputParameters),用于结果集二次处理。
StatementHandler (prepare, parameterize, batch, update, query),用于jdbc层的控制。
大多数情况下仅在Executor做插件比如SQL重写、结果集脱敏,ResultSetHandler和StatementHandler仅在高级场景中使用,而且某些场景中非常有价值。

四大对象的在sql执行过程中的调用链如下:
在这里插入图片描述

1,拦截器接口介绍

Mybatis插件可以用来实现拦截器接口Interceptor,在实现类中拦截对象和方法进行处理。
先看拦截器接口,了解该接口中的每一个方法的作用和用法,代码如下:

public interface Interceptor {

  Object intercept(Invocation invocation) throws Throwable;

  Object plugin(Object target);

  void setProperties(Properties properties);

}

1,setProperties:这个方法时用来传递插件的参数可以通过参数来改变插件的行为。如何传递?如下:

	<plugins>
        <plugin interceptor="person.david.ssm.interceptor.CameHumpInterceptor">
        <property name="prop1" value="value1"/>
                <property name="prop1" value="value1"/>
				<property name="prop2" value="value2"/>
		</plugin>
    </plugins>

2,plugin:这个方法的参数就是拦截器要拦截的对象,该方法会在创建被拦截的接口实现类时被调用。通常实现方法如下:

@Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

3,interceptor:这个方法是Mybatis运行时要执行的拦截方法,该参数invocation可以获得很多有用的信息,通常实现方法如下:

@Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        onject result = invocation.proceed();
        return result;
    }

2,拦截器签名介绍

除了需要实现拦截器接口外,还需要给实现类配置以下的拦截器注解。

@Intercepts和@Signature这两个注解用来配置拦截器拦截的接口的方法,@Intercepts注解中的属性是一个@Signature(签名)数组,可以在同一个拦截器中同时拦截不同的接口和方法。

以拦截ResultSetHandler接口的handleResultSets方法为例,配置签名如下:

@Intercepts(
        @Signature(
                type = ResultSetHandler.class,
                method = "handleResultSets",
                args = {Statement.class})

)
@SuppressWarnings({"unchecked","rawtypes"})
public class ResultSetInterceptor implements Interceptor

@Signature注解包含以下三个属性:


 - type:设置拦截的接口,可选值是前面提到的四个接口
 - method:设置拦截接口中的方法名,可选值是前面四个接口对应的方法,需要和接口匹配
 - args:设置拦截方法的参数类型数组,通过方法名和参数类型可以确定唯一一个方法

3,接口使用介绍

发布了72 篇原创文章 · 获赞 21 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_39513430/article/details/104326275