mybatis interceptor(攔截器) 監(jiān)控語句執(zhí)行時間

公司沒有運維,沒有DBA,大家只管寫SQL,能夠查詢出來結(jié)果就行,有時候也搞不清楚哪種寫法更加的高效,最開始的時候沒有數(shù)據(jù)量也沒有性能的對比,當然大公司請忽略這個了,因為阿里云RDS自己有監(jiān)控,DBA會優(yōu)化sql,先看看簡單的代碼


import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
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.Plugin;
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, CacheKey.class, BoundSql.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class,
            ResultHandler.class})
    }
)
@Slf4j
public class TimerInterceptor implements Interceptor {

  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    try {
      Object[] args = invocation.getArgs();
      MappedStatement ms = (MappedStatement) args[0];
      Object parameter = args[1];
      Object p;
      //這里的參數(shù)這樣判斷是因為加了@Param的和沒有加的好像有點區(qū)別,調(diào)試的時候看到的
      if (parameter instanceof Map) {
        Map map = (Map) parameter;
        HashSet<Object> set = new HashSet<>();
        set.addAll(map.values());
        p = set;
      } else {
        p = parameter;
      }
      Object result;
      long start = System.currentTimeMillis();
      result = invocation.proceed();
      long end = System.currentTimeMillis();
      long cost = end - start;
      log.debug("[TimerInterceptor] execute [{}] cost [{}] ms, parameter:{}", ms.getId(), cost, p);
      if (cost > 2000) {//這里的時間根據(jù)情況設定,也可以寫在配置文件里面
        log.warn("Sql語句執(zhí)行時間超過2秒鐘,請檢查優(yōu)化,方法:{},耗時:{}ms,參數(shù):{}", ms.getId(), cost, p);
      }
      return result;
    } catch (Throwable r) {
      log.error(r.getMessage(), r);
    }
    return invocation.proceed();
  }

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

  @Override
  public void setProperties(Properties properties) {

  }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容