如何为 MyBatis 语句创建性能监听器

问题描述 投票:0回答:2

我想为 MyBatis 语句创建一种服务质量,一种全局性能监听器,它将分析所有已执行的 MyBatis 语句并记录那些返回太多命中或花费太长时间的语句。如果可能,尽可能减少对现有业务逻辑的影响。

java performance listener mybatis ibatis
2个回答
0
投票

您可以创建拦截器接口的实现并将其注册为配置文件中的插件。


0
投票

我只做了一个快速测试,但是像下面这样的自定义拦截器(又名插件)应该可以完成这项工作。

仅当 1) 日志级别为 DEBUG 或更精细且 2) 执行时间超过常量

THRESHOLD_NANOS
的值时才会记录消息。

import java.text.MessageFormat;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

@Intercepts({
  @Signature(
      type = Executor.class,
      method = "update",
      args = { MappedStatement.class, Object.class }),
  @Signature(
      type = Executor.class,
      method = "query",
      args = { MappedStatement.class, Object.class,
        RowBounds.class, ResultHandler.class })
})
public class LogExecutionTimeInterceptor implements Interceptor {

  private static final Log log = LogFactory.getLog(LogExecutionTimeInterceptor.class);

  private static final long THRESHOLD_NANOS = 0L;

  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    long before = System.nanoTime();
    Object result = invocation.proceed();
    long duration = System.nanoTime() - before;

    if (duration > THRESHOLD_NANOS && log.isDebugEnabled()) {
      MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
      log.debug(MessageFormat.format(
          "Statement {0} took {1} nano seconds", mappedStatement.getId(), duration));
    }
    return result;
  }

}

注册拦截器...

  1. 使用 XML 配置
<plugins>
  <plugin
      interceptor="xxx.yyy.LogExecutionTimeInterceptor" />
</plugins>
  1. mybatis-spring-boot-starter
@Bean
Interceptor getLogExecutionTimeInterceptor() {
  return new LogExecutionTimeInterceptor();
}
© www.soinside.com 2019 - 2024. All rights reserved.