1.目录
2.代码
package com. sunxiansheng. mybatis. plus. inteceptor ; import org. apache. ibatis. executor. statement. StatementHandler ;
import org. apache. ibatis. mapping. * ;
import org. apache. ibatis. plugin. * ;
import org. apache. ibatis. reflection. * ;
import org. apache. ibatis. session. Configuration ;
import org. apache. ibatis. session. ResultHandler ;
import org. apache. ibatis. type. TypeHandlerRegistry ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ;
import com. github. vertical_blank. sqlformatter. SqlFormatter ;
import com. github. vertical_blank. sqlformatter. languages. Dialect ;
import com. google. gson. Gson ;
import com. google. gson. GsonBuilder ; import java. sql. Statement ;
import java. util. List ;
import java. util. Properties ;
import java. util. regex. Matcher ;
@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 } )
} )
public class SqlBeautyInterceptor implements Interceptor { private static final Logger logger = LoggerFactory . getLogger ( SqlBeautyInterceptor . class ) ; private static final String ANSI_RESET = "\u001B[0m" ; private static final String ANSI_BRIGHT_GREEN = "\u001B[92m" ; private static final String ANSI_BRIGHT_BLUE = "\u001B[94m" ; private static final Gson GSON = new GsonBuilder ( ) . setPrettyPrinting ( ) . disableHtmlEscaping ( ) . create ( ) ; @Override public Object intercept ( Invocation invocation) throws Throwable { StatementHandler statementHandler = ( StatementHandler ) invocation. getTarget ( ) ; MetaObject metaObject = SystemMetaObject . forObject ( statementHandler) ; while ( metaObject. hasGetter ( "h" ) ) { Object object = metaObject. getValue ( "h" ) ; metaObject = SystemMetaObject . forObject ( object) ; } while ( metaObject. hasGetter ( "target" ) ) { Object object = metaObject. getValue ( "target" ) ; metaObject = SystemMetaObject . forObject ( object) ; } MappedStatement mappedStatement = ( MappedStatement ) metaObject. getValue ( "delegate.mappedStatement" ) ; BoundSql boundSql = ( BoundSql ) metaObject. getValue ( "delegate.boundSql" ) ; Configuration configuration = mappedStatement. getConfiguration ( ) ; long startTime = System . currentTimeMillis ( ) ; Object result = null ; try { result = invocation. proceed ( ) ; return result; } finally { long endTime = System . currentTimeMillis ( ) ; long sqlCost = endTime - startTime; SqlCommandType sqlCommandType = mappedStatement. getSqlCommandType ( ) ; String formattedSql = formatSql ( configuration, boundSql) ; String formattedResult = formatResult ( result, sqlCommandType) ; logger. info ( "\n========================\n{}SQL 类型:{} {}{}{}\n{}SQL:{}\n{}{}{}\n{}执行耗时:{} {}{}ms{} \n{}结果:{}\n{}{}\n{}========================{}" , ANSI_BRIGHT_BLUE , ANSI_RESET , ANSI_BRIGHT_GREEN , sqlCommandType, ANSI_RESET , ANSI_BRIGHT_BLUE , ANSI_RESET , ANSI_BRIGHT_GREEN , formattedSql, ANSI_RESET , ANSI_BRIGHT_BLUE , ANSI_RESET , ANSI_BRIGHT_GREEN , sqlCost, ANSI_RESET , ANSI_BRIGHT_BLUE , ANSI_RESET , ANSI_BRIGHT_GREEN , formattedResult, ANSI_RESET , ANSI_BRIGHT_BLUE , ANSI_RESET ) ; } } @Override public Object plugin ( Object target) { return Plugin . wrap ( target, this ) ; } @Override public void setProperties ( Properties properties) { } private String formatSql ( Configuration configuration, BoundSql boundSql) { try { String sql = boundSql. getSql ( ) ; Object parameterObject = boundSql. getParameterObject ( ) ; List < ParameterMapping > parameterMappings = boundSql. getParameterMappings ( ) ; if ( parameterMappings != null && ! parameterMappings. isEmpty ( ) && parameterObject != null ) { TypeHandlerRegistry typeHandlerRegistry = configuration. getTypeHandlerRegistry ( ) ; MetaObject metaObject = configuration. newMetaObject ( parameterObject) ; for ( ParameterMapping parameterMapping : parameterMappings) { String propertyName = parameterMapping. getProperty ( ) ; Object value; if ( boundSql. hasAdditionalParameter ( propertyName) ) { value = boundSql. getAdditionalParameter ( propertyName) ; } else if ( metaObject. hasGetter ( propertyName) ) { value = metaObject. getValue ( propertyName) ; } else if ( typeHandlerRegistry. hasTypeHandler ( parameterObject. getClass ( ) ) ) { value = parameterObject; } else { value = null ; } sql = replaceFirstQuestionMark ( sql, getParameterValue ( value) ) ; } } return SqlFormatter . of ( Dialect. MySql ) . format ( sql) ; } catch ( Exception e) { logger. error ( "Error formatting SQL: " , e) ; return boundSql. getSql ( ) ; } } private String replaceFirstQuestionMark ( String sql, String value) { return sql. replaceFirst ( "\\?" , Matcher . quoteReplacement ( value) ) ; } private String getParameterValue ( Object obj) { if ( obj == null ) { return "null" ; } if ( obj instanceof String ) { return "'" + obj + "'" ; } if ( obj instanceof Number ) { return obj. toString ( ) ; } if ( obj instanceof java. util. Date || obj instanceof java. sql. Date || obj instanceof java. sql. Timestamp) { return "'" + obj. toString ( ) + "'" ; } return "'" + obj. toString ( ) + "'" ; } private String formatResult ( Object result, SqlCommandType sqlCommandType) { if ( result == null ) { return "null" ; } try { String formattedResult; if ( sqlCommandType == SqlCommandType . SELECT ) { formattedResult = GSON . toJson ( result) ; } else if ( sqlCommandType == SqlCommandType . UPDATE || sqlCommandType == SqlCommandType . DELETE || sqlCommandType == SqlCommandType . INSERT ) { formattedResult = result. toString ( ) + " 行受影响" ; } else { formattedResult = result. toString ( ) ; } int maxLength = 2000 ; if ( formattedResult. length ( ) > maxLength) { formattedResult = formattedResult. substring ( 0 , maxLength) + "... [结果过长,已截断]" ; } return formattedResult; } catch ( Exception e) { logger. error ( "Error formatting result: " , e) ; return result. toString ( ) ; } }
}