直接上代码,自己看,粘贴可用
package com.example.demo.mybatis;import com.baomidou.mybatisplus.core.toolkit.PluginUtils;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;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.ResultHandler;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import java.sql.Statement;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Properties;/*** 描述:Sql执行时间记录拦截器 </br>* 作者:王林冲 </br>* 时间:2022-12-12 14:11*/@Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),@Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),@Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})})@Componentpublic class SqlExecuteTimeCountInterceptor implements Interceptor {private static Logger logger = LoggerFactory.getLogger(SqlExecuteTimeCountInterceptor.class);/*** 打印的参数字符串的最大长度*/private final static int MAX_PARAM_LENGTH = 50;/*** 记录的最大SQL长度*/private final static int MAX_SQL_LENGTH = 200;@Overridepublic Object intercept(Invocation invocation) throws Throwable {Object target = invocation.getTarget();long startTime = System.currentTimeMillis();StatementHandler statementHandler = (StatementHandler) target;try {return invocation.proceed();} finally {long endTime = System.currentTimeMillis();long timeCount = endTime - startTime;//获取BoundSqlBoundSql boundSql = statementHandler.getBoundSql();//获取原始sqlString sql = boundSql.getSql();Object parameterObject = boundSql.getParameterObject();List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();// 格式化Sql语句,去除换行符,替换参数sql = formatSQL(sql, parameterObject, parameterMappingList);logger.info("=======> 执行 SQL:{} 执行耗时 {} ms", sql, timeCount);PluginUtils.MPStatementHandler mpStatementHandler = PluginUtils.mpStatementHandler(statementHandler);List<String> paramList = handleParameterToStr(mpStatementHandler);String paramStr = String.join(", ", paramList);logger.info("=======> 条件参数:{}" ,paramStr );}}private List<Object> handleParameter(PluginUtils.MPStatementHandler mpSh) {List<Object> values = new ArrayList();Object parameterObject = mpSh.boundSql().getParameterObject();List<ParameterMapping> parameterMappings = mpSh.boundSql().getParameterMappings();if (parameterMappings != null) {Iterator var5 = parameterMappings.iterator();while(var5.hasNext()) {ParameterMapping parameterMapping = (ParameterMapping)var5.next();if (parameterMapping.getMode() != ParameterMode.OUT) {String propertyName = parameterMapping.getProperty();Object value;if (mpSh.boundSql().hasAdditionalParameter(propertyName)) {value = mpSh.boundSql().getAdditionalParameter(propertyName);} else if (parameterObject == null) {value = null;} else if (mpSh.configuration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) {value = parameterObject;} else {MetaObject metaObject = mpSh.configuration().newMetaObject(parameterObject);value = metaObject.getValue(propertyName);}values.add(value);}}}return values;}private List<String> handleParameterToStr(PluginUtils.MPStatementHandler mpSh) {List<Object> objects = handleParameter(mpSh);List<String> values = new ArrayList<>(objects.size());objects.forEach(e -> {values.add(objToStr(e));});return values;}private String objToStr (Object o){StringBuffer sb =new StringBuffer(o.toString());sb.append("(");sb.append(o.getClass().getSimpleName()) ;sb.append(")");String str = sb.toString();return str;}/*** 格式化/美化 SQL语句** @param sql sql 语句* @param parameterObject 参数的Map* @param parameterMappingList 参数的List* @return 格式化之后的SQL*/private String formatSQL(String sql, Object parameterObject, List<ParameterMapping> parameterMappingList) {// 输入sql字符串空判断if (sql == null || sql.length() == 0) {return "";}// 美化sqlsql = beautifySql(sql);// 不传参数的场景,直接把sql美化一下返回出去if (parameterObject == null || parameterMappingList == null || parameterMappingList.size() == 0) {return sql;}return LimitSQLLength(sql);}/*** 返回限制长度之后的SQL语句*** @param sql 原始SQL语句*/private String LimitSQLLength(String sql) {if (sql == null || sql.length() == 0) {return "";}if (sql.length() > MAX_SQL_LENGTH) {return sql.substring(0, MAX_SQL_LENGTH);} else {return sql;}}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}/*** 替换SQL 中? 所对应的值, 只保留前50个字符** @param sql sql语句* @param valueOf ?对应的值*/private String replaceValue(String sql, String valueOf) {//超过50个字符只取前50个if (valueOf != null && valueOf.length() > MAX_PARAM_LENGTH) {valueOf = valueOf.substring(0, MAX_PARAM_LENGTH);}sql = sql.replaceFirst("\\?", valueOf);return sql;}/*** 美化sql** @param sql sql语句*/private String beautifySql(String sql) {sql = sql.replaceAll("[\\s\n ]+", " ");return sql;}}
文章转载自IT学习道场,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




