利用mybatis插件功能实现慢sql监控

  • Post author:
  • Post category:其他


首先在mybatis全局配置文件中加入如下配置。

<plugins>
	//自定义的插件类
	<plugin interceptor="com.wyl.mybatis.Interceptors.ThresholdInterceptor">
		//定义一个属性值用来配置慢sql的时间
		<property name="slowSqlTime" value="10000"/>
	</plugin>
</plugins>

自定义插件类,配置拦截的方法。

/**
	拦截StatementHandler接口中如下方法
	<E> List<E> query(Statement statement, ResultHandler resultHandler)
      throws SQLException;
*/
@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})

也就是将在生成预编译sql语句并准备执行sql语句之前和执行完sql语句并拿到结果集之后。

@Override
  public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    return resultSetHandler.handleResultSets(ps);
  }
@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})
})
//实现Interceptor接口
public class ThresholdInterceptor implements Interceptor {

    private long slowSqlTime;

	/**
	处理业务逻辑的方法
	*/
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        //之前拦截方法,即query那个方法
        Object object = invocation.proceed();
        long end = System.currentTimeMillis();
        long countTime = end - start;
        if (countTime >= slowSqlTime) {
        	//获取PreparedStatementLogger代理类,mybatis日志功能通过动态代理把PreparedStatement包装成了PreparedStatementLogger
            Object[] args = invocation.getArgs();
            Statement statement = (Statement) args[0];
            //通过反射得到目标对象
            MetaObject metaObjectStat = SystemMetaObject.forObject(statement);
            //拿到代理对象实例
            PreparedStatementLogger statementLogger = (PreparedStatementLogger) metaObjectStat.getValue("h");
            Statement preparedStatement = statementLogger.getPreparedStatement();
            System.out.println("当前sql:" + preparedStatement.toString() + ",执行时间为:" + countTime + "毫秒,监控为慢sql!");
        }
        return object;
    }

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

	//拿到配置文件中设置的阈值
    @Override
    public void setProperties(Properties properties) {
        this.slowSqlTime = Long.valueOf(properties.getProperty("slowSqlTime"));
    }
}

invocation中的内容。

在这里插入图片描述

最后输出。

当前sql:com.mysql.jdbc.JDBC4PreparedStatement@5a1de7fb: select
		id, userName
		from t_user
		where id = 2,执行时间为:16毫秒,监控为慢sql!



版权声明:本文为CSDN_WYL2016原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。