您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
这篇文章主要介绍“mybatis如何使用拦截器interceptor对sql打印,使执行的sql在日志中可见”,在日常操作中,相信很多人在mybatis如何使用拦截器interceptor对sql打印,使执行的sql在日志中可见问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”mybatis如何使用拦截器interceptor对sql打印,使执行的sql在日志中可见”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
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.mapping.ParameterMapping; 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.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 java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Properties; /** * @author kxd * @date 2019/10/25 15:55 * description: */ @Intercepts({ @Signature( method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} ), @Signature(method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class} ) }) @Slf4j public class LogInterceptor implements Interceptor { /** * 是否显示语句的执行时间 */ public static final String PROPERTIES_KEY_ENABLE_EXECUTOR_TIME = "enableExecutorTIme"; public static final String NO = "NO"; public static final String YES = "YES"; private String enableExecutorTime; /** * 执行逻辑 * * @param invocation * @return * @throws Throwable */ @Override public Object intercept(Invocation invocation) throws Throwable { if (enableExecutorTime.equals(YES)) { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; //这里是为了找到上层是哪个方法触发了这个拦截器 Object parameter = null; if (invocation.getArgs().length > 1) { parameter = invocation.getArgs()[1]; } String sqlId = mappedStatement.getId(); BoundSql boundSql = mappedStatement.getBoundSql(parameter); Configuration configuration = mappedStatement.getConfiguration(); long sqlStartTime = System.currentTimeMillis(); Object next = invocation.proceed(); long sqlEndTime = System.currentTimeMillis(); String sql = getSql(configuration, boundSql, sqlId); String sqlTimeLog = sqlId.concat(">>runs :").concat(String.valueOf(sqlEndTime - sqlStartTime)).concat("ms"); log.info(">>>>>>>>>>>>>runs method:{}", sqlTimeLog); log.info(">>>>>>>>>>>>>content:{}", sql); return next; } return invocation.proceed(); } private String getSql(Configuration configuration, BoundSql boundSql, String sqlId) { return sqlId + ">>execute sql:" + assembleSql(configuration, boundSql); } /** * 组装sql信息 * * @param configuration * @param boundSql * @return */ private String assembleSql(Configuration configuration, BoundSql boundSql) { Object sqlParameter = boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); String sql = boundSql.getSql().replaceAll("[\\s+]", "").replaceAll("from", "\n\tFROM\n\t").replaceAll("select", "\n\tSELECT\t\n"); if (parameterMappings.size() > 0 && sqlParameter != null) { TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); if (typeHandlerRegistry.hasTypeHandler(sqlParameter.getClass())) { sql = sql.replaceFirst("\\?", getParameterValue(sqlParameter)); } else { MetaObject metaObject = configuration.newMetaObject(sqlParameter); for (ParameterMapping parameterMapping : parameterMappings) { String propertyName = parameterMapping.getProperty(); if (metaObject.hasGetter(propertyName)) { Object obj = metaObject.getValue(propertyName); sql = sql.replaceFirst("\\?", getParameterValue(obj)); } else if (boundSql.hasAdditionalParameter(propertyName)) { Object obj = boundSql.getAdditionalParameter(propertyName); sql = sql.replaceFirst("\\?", getParameterValue(obj)); } } } } return sql; } /** * 获取参数对应string值 * * @param obj * @return */ private String getParameterValue(Object obj) { String value = ""; if (obj instanceof String) { value = "'".concat(obj.toString()).concat("'"); } else if (obj instanceof Date) { DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA); value = "'".concat(dateFormat.format(new Date())) + "'"; } else { if (obj != null) { value = obj.toString(); } else { value = ""; } } return value != null ? makeStringAllRegExp(value) : value; } /** * 转义正则特殊字符串 * * @param str * @return */ private String makeStringAllRegExp(String str) { if (str != null && !str.equals("")) { return str.replace("\\", "\\\\").replace("*", "\\*") .replace("+", "\\+").replace("|", "\\|") .replace("{", "\\{").replace("}", "\\}") .replace("(", "\\(").replace(")", "\\)") .replace("^", "\\^").replace("$", "\\$") .replace("[", "\\[").replace("]", "\\]") .replace("?", "\\?").replace(",", "\\,") .replace(".", "\\.").replace("&", "\\&"); } return str; } /** * 返回代理对象 * * @param target * @return */ @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } /** * 设置属性信息 * * @param properties */ @Override public void setProperties(Properties properties) { if (properties != null) { String executorTimeValue = properties.getProperty(PROPERTIES_KEY_ENABLE_EXECUTOR_TIME); if (executorTimeValue != null) { enableExecutorTime = executorTimeValue; } } } }
到此,关于“mybatis如何使用拦截器interceptor对sql打印,使执行的sql在日志中可见”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。