[mybatis]mybatis自定义拦截器,统计SQL执行耗时

本文介绍如何在MyBatis中实现SQL执行时间的拦截与记录,通过自定义拦截器插件,掌握其核心流程及配置方法,确保SQL执行效率的监控。

在编写mybatis拦截器之前,应该知道mybatis大致的执行流程

  1. 读取配置(xml),或者是与springboot整合的MybatisAutoConfiguration,都是在进行初始化配置,配置SqlSessionFactory和org.apache.ibatis.session.Configuration
  2. 执行SQL时创建SqlSession会话,生成执行器(Executor)
  3. SQL语句处理 StatementHandler
  4. 参数处理 ParameterHandler
  5. 结果集处理 ResultSetHandler

大致清楚这几个流程之后就可以编写拦截器插件了,代码

/**
 * mybatis的插件,用于记录SQL执行时间,记录的SQL类型包含:query、update
 *
 * @author lihaoran
 */
@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class,
                Object.class, RowBounds.class, ResultHandler.class}),
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
                Object.class})
})
public class MybatisSQLExecutionInterceptor implements Interceptor {
    private final Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Long startTime = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            Long endTime = System.currentTimeMillis();
            Long time = endTime - startTime;
            log.debug("SQL执行耗时:{}ms", time);
        }
    }

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

    @Override
    public void setProperties(Properties properties) {
    }
}

查询拦截了RowBounds.class, ResultHandler.class ,更新没有,因为更新是不需要结果集映射的,只需知道影响的记录数就好。
基础的拦截器已经开发完成,只需让它生效就好。生效的几种方式:

  1. 在配置文件中(yml.xml)声明,
    在这里插入图片描述
    这种方式我是没找到怎么写,好像是用不了,所以只能选择其他
  2. 声明bean的方式,其实百度上不少都是@Configuration @Bean的这种方式,可行,但是自己不太想用
  3. 使用自动配置的方式,就相当于做个自动启动器,只不过这个启动器不需要给外部用,所以也不用在META-INF中新建spring.provides这种方式(类似于spi吧)。

所以选择第三种

@Configuration
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class MybatisPluginAutoConfiguration {

    @Autowired
    public MybatisPluginAutoConfiguration(SqlSessionFactory fac){
        org.apache.ibatis.session.Configuration con = fac.getConfiguration();
        con.addInterceptor(new MybatisSQLExecutionInterceptor());
    }
}

mybatis自动配置类

@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration implements InitializingBean {

 @Bean
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    }
}

这里面声明在做一件事 声明SqlSessionFactory ,如果不存在创建它;存在就忽略呗,这也是自己手动配置SqlSessionFactory,自己的可以生效的原因,当然还有个优先级的关系

至此,统计SQL执行耗时的插件已经完成。
通过Configuration con.addInterceptor(new MybatisSQLExecutionInterceptor());点进去这个方法可以看到 将拦截器添加到拦截器链,这样顺序添加的插件应该能顺序执行。(毕竟是个list)在这里插入图片描述

运行截图:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值