阅读 387
Mybatis插件基本使用

Mybatis插件基本使用

前言

mybatis允许使用插件来拦截以下四种类型的方法调用。类似于spring aop。

Executor.class:主要作用是执行sql。
ParameterHandler.class:主要作用是设置参数。
ResultSetHandler.class:主要作用是对查询结果进行映射处理。
StatementHandler.class:主要作用是负责处理mybatis与jdbc之间statement交互。
复制代码

第一步:定义插件

实现插件,我们需要实现Interceptor接口。
@Intercepts中声明拦截哪个方法。
@Signature定义具体的方法。通过三个参数具体定位到拦截哪个类型的哪个方法。

  • type=>表示拦截哪一个类型,四种类型如上。
  • method=> 指定上面type接口中的方法。
  • args => 指定method所携带的参数类型。
@Intercepts({
        // 表示拦截Executor中的参数为args指定顺序的参数类型的query方法
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class,
                Object.class, RowBounds.class, ResultHandler.class})
})
public class SqlInterceptor implements Interceptor {
    // 代理对象每次拦截调用的方法
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object parameter = null;
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];

        if (invocation.getArgs().length > 1) {
            // parameter = {deptName=haha, deptNo=1, param1=1, param2=haha}
            parameter = invocation.getArgs()[1];
        }
        Configuration configuration = mappedStatement.getConfiguration();
        // 获取sql包装类
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        // invocation.proceed() 执行sql
        return invocation.proceed();
    }
    
    @Override
    public Object plugin(Object target) {
        // 默认写法:返回当前对象的代理对象,只有返回代理对象的时候,才会调用intercept方法。
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
       // properties表示注册插件时设置的属性
    }
}
复制代码

如果需要拦截其它类型的其它方法,均可进入接口中查看有哪些方法,在@Signature中指定即可。重要的一点是,一定要返回代理对象,否则无法调用intercept方法,造成拦截器不生效。

第二步:注册插件

<!-- mybatis-config.xml -->
<plugins>
    <plugin interceptor="com.shang.interceptor.NoSqlInterceptor">
        <property name="limit" value="10"/>
        <property name="deptNo" value="2"/>
    </plugin>
</plugins>
复制代码

总结

当你想在sql执行过程中,需要在哪一步进行改造的时候,你可能不仅要了解上面的知识,还要了解几个重要的核心对象

核心对象作用
SqlSession和数据库交互的会话,完成增删改查
Executor执行器,负责sql语句生成和查询缓存
StatementHandler封装jdbc statement 操作,如设置参数、将statement结果集转换成List集合
ParameterHandler将用户传递的参数转换成 jdbc statement 所需要的参数
ResultSetHandler将 reslutSet 结果集转换成 List 集合
TypeHandler负责java数据类型和jdbc数据类型之间的映射和转换
MappedStatement维护一条mapper.xml文件里的select、update、delete、insert
SqlSource负责根据用户传递的parameterObject,动态生成sql语句,将信息封装到BoundSql对象中,并返回
BoundSql动态生成的sql语句以及相应的参数信息
Configurationmybatis所有配置信息都维护在Configuration对象中

思路Invocation是传进来的参数类型,你可以debugargs中查看有哪些对象,然后获取参数中的对象,对sql进行改造。

public class Invocation {
    // 目标对象
    private final Object target;
    // 目标方法
    private final Method method;
    // 参数
    private final Object[] args;
    // 反射执行目标方法
    public Object proceed() throws InvocationTargetException, IllegalAccessException {
        return this.method.invoke(this.target, this.args);
    }
}
复制代码
文章分类
后端
文章标签