mybatis 的进阶使用拦截器

文章思路

学一个东西咱们首先要弄清楚它的使用场景 ,否则毫无心义。下面首先介绍 mybatis 插件的使用场景,而后再介绍如何使用,最后是它的原理 。java

使用场景

  1. 首先是网上都在说的分页插件,这个已经有人实现了,可使用 PageHelper 插件,咱们能够学习它怎么作的,但不必重复造轮子,直接用就能够了
  2. 使用 mybatis 的时候发现若是是 PrepareStatement 的时候 ,sql 语句和参数是分开的,查找问题时很是不方便,这时候能够自定义插件把整合后的 sql 打印在控制台上。固然生产上须要关闭这个功能,由于不可能把大量的 sql 打印在日志文件中。
  3. 统计慢查询,能够用 mybatis 插件,设置一个慢查询阈值,把慢的 select 查询发送到消息中间件或存储在 mongodb 等,而后在页面作一个慢查询可视化来监控慢查询。
  4. 数据权限,这个我在项目中用过,可使用 jsqlParser 来增长 sql 根据当前登陆用户来追加查询条件,而不用硬编码在 sql 语句中。

如何使用

实现 org.apache.ibatis.plugin.Interceptor 接口,并指明要拦截 Mybatis 哪一个类的哪一个方法,而后把其注册到 mybatis 插件中就能够了。git

Mybatis拦截器只能拦截Executor、ParameterHandler、StatementHandler、ResultSetHandler四个对象里面的方法。sql

可拦截对象 解释
Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所须要的参数
StatementHandler 封装了JDBC Statement操做,负责对JDBC statement 的操做,如设置参数、将Statement结果集转换成List集合
ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;

快速使用,打印查询方法执行时间

  1. 定义拦截器
  2. 注册到 plugins 中,能够注册多个
@Intercepts(
        // 拦截 Executor.query 方法,不是查缓存那个
        @Signature(type = Executor.class,method = "query",args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class})
)
@Slf4j
public class TimeSpendInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StopWatch stopWatch = new StopWatch();stopWatch.start();
        // Invocation 的参数是看拦截的方法来的,这里 query 方法第一个参数是语句对象
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        String id = mappedStatement.getId();
        Object proceed = null;
        try {
            proceed =  invocation.proceed();
        }finally {
            stopWatch.stop();
            log.info("sqlId:"+id+" 执行时间为:"+stopWatch.getTime()+" ms");
        }
        return proceed;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }
}
@Configuration
public class MybatisConfig {
    @Bean("timeSpendInterceptor")
    public Interceptor interceptor2(){
        return new TimeSpendInterceptor();
    }
}

最后成果:
[ sqlId:com.sanri.test.testmybatis.mapper.BatchMapper.selectAll 执行时间为:548 ms ]mongodb

完整项目地址

https://gitee.com/sanri/example/tree/master/test-mybatis数据库

一些小推广

Excel 通用导入导出,支持 Excel 公式
https://blog.csdn.net/sanri1993/article/details/100601578apache

使用模板代码 ,从数据库生成代码 ,及一些项目中常常能够用到的小工具
https://blog.csdn.net/sanri1993/article/details/98664034缓存

相关文章
相关标签/搜索