java拦截执行的sql,Mybatis 实现SQL拦截并在控制台打印SQL和参数

注:可以拦截sql 执行时间,优化sql。并打印sql 以及参数

第一步:创建类:

SqlPrintInterceptor 并实现 Interceptor

该类如下:

package com.ra.common.plugin;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.mapping.ParameterMapping;

import org.apache.ibatis.mapping.ParameterMode;

import org.apache.ibatis.plugin.*;

import org.apache.ibatis.reflection.MetaObject;

import org.apache.ibatis.session.Configuration;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import org.apache.ibatis.type.TypeHandlerRegistry;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.List;

import java.util.Properties;

import java.util.regex.Matcher;

/*

* MyBatis 将mybatis要执行的sql拦截打印出来

*/

@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 SqlPrintInterceptor implements Interceptor{

private static final Logger log = LoggerFactory.getLogger(SqlPrintInterceptor.class);

private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

@Override

public Object intercept(Invocation invocation) throws Throwable {

MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];

Object parameterObject = null;

if (invocation.getArgs().length > 1) {

parameterObject = invocation.getArgs()[1];

}

long start = System.currentTimeMillis();

Object result = invocation.proceed();

String statementId = mappedStatement.getId();

BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);

Configuration configuration = mappedStatement.getConfiguration();

String sql = getSql(boundSql, parameterObject, configuration);

long end = System.currentTimeMillis();

long timing = end - start;

//根据个人喜好看需要打印怎么sql,本人是打印打印  1s的

if(log.isInfoEnabled() && timing>1000){

log.info("执行sql耗时:" + timing + " ms" + " - id:" + statementId + " - Sql:" );

log.info(" "+sql);

}

return result;

}

@Override

public Object plugin(Object target) {

if (target instanceof Executor) {

return Plugin.wrap(target, this);

}

return target;

}

@Override

public void setProperties(Properties properties) {

}

private String getSql(BoundSql boundSql, Object parameterObject, Configuration configuration) {

String sql = boundSql.getSql().replaceAll("[\\s]+", " ");

List parameterMappings = boundSql.getParameterMappings();

TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();

if (parameterMappings != null) {

for (int i = 0; i < parameterMappings.size(); i++) {

ParameterMapping parameterMapping = parameterMappings.get(i);

if (parameterMapping.getMode() != ParameterMode.OUT) {

Object value;

String propertyName = parameterMapping.getProperty();

if (boundSql.hasAdditionalParameter(propertyName)) {

value = boundSql.getAdditionalParameter(propertyName);

} else if (parameterObject == null) {

value = null;

} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {

value = parameterObject;

} else {

MetaObject metaObject = configuration.newMetaObject(parameterObject);

value = metaObject.getValue(propertyName);

}

sql = replacePlaceholder(sql, value);

}

}

}

return sql;

}

private String replacePlaceholder(String sql, Object propertyValue) {

String result;

if (propertyValue != null) {

if (propertyValue instanceof String) {

result = "'" + propertyValue + "'";

} else if (propertyValue instanceof Date) {

result = "'" + DATE_FORMAT.format(propertyValue) + "'";

} else {

result = propertyValue.toString();

}

} else {

result = "null";

}

return sql.replaceFirst("\\?", Matcher.quoteReplacement(result));

}

}

第二步:在mybatis-config.xml 文件加上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值