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

huangapple go评论68阅读模式
英文:

How to create performance listener for MyBatis statements

问题

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

英文:

I would like to create a sort of Quality of Service for MyBatis statements, a sort of global performance listener which will analyze all executed MyBatis statements and log those that return too many hits or take too long. If possible in such a way that the impact on the existing business logic is as small as possible.

答案1

得分: 1

I only did a quick test, but a custom interceptor (a.k.a. plugin) like the following should do the job.

以下是要翻译的内容:

The message is logged only when 1) the log level is DEBUG or finer and 2) the execution time exceeds the value of the constant THRESHOLD_NANOS.

只有在以下条件满足时才记录该消息:1)日志级别为DEBUG或更高级别,2)执行时间超过常量THRESHOLD_NANOS的值。

To register the interceptor...

要注册拦截器...

  1. with XML configuration

  2. 使用XML配置

<plugins>
  <plugin
      interceptor="xxx.yyy.LogExecutionTimeInterceptor" />
</plugins>
  1. with mybatis-spring-boot-starter

  2. 使用mybatis-spring-boot-starter进行配置

@Bean
Interceptor getLogExecutionTimeInterceptor() {
  return new LogExecutionTimeInterceptor();
}
英文:

I only did a quick test, but a custom interceptor (a.k.a. plugin) like the following should do the job.

The message is logged only when 1) the log level is DEBUG or finer and 2) the execution time exceeds the value of the constant 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 = &quot;update&quot;,
      args = { MappedStatement.class, Object.class }),
  @Signature(
      type = Executor.class,
      method = &quot;query&quot;,
      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 &gt; THRESHOLD_NANOS &amp;&amp; log.isDebugEnabled()) {
      MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
      log.debug(MessageFormat.format(
          &quot;Statement {0} took {1} nano seconds&quot;, mappedStatement.getId(), duration));
    }
    return result;
  }

}

To register the interceptor...

  1. with XML configuration
&lt;plugins&gt;
  &lt;plugin
      interceptor=&quot;xxx.yyy.LogExecutionTimeInterceptor&quot; /&gt;
&lt;/plugins&gt;
  1. with mybatis-spring-boot-starter
@Bean
Interceptor getLogExecutionTimeInterceptor() {
  return new LogExecutionTimeInterceptor();
}

答案2

得分: 0

你可以创建Interceptor接口的实现,并在配置文件中将其注册为插件。

英文:

You can create implementation of Interceptor interface and register it as a plugin in configuration file.

huangapple
  • 本文由 发表于 2023年4月19日 16:50:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052513.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定