您好,登錄后才能下訂單哦!
這篇文章主要介紹“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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。