1.实现拦截器
package com.sample.common.interceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
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.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.springframework.util.ObjectUtils;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
/**
* @author: Alex Hu
* @createTime: 2024/08/16 07:46
* Custom SQL interceptor to print SQL and execution time
*/
@Slf4j
public class MyBatisPlusSqlInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
long startTime = System.currentTimeMillis();
try {
String printSql = generateSql(ms, parameter, boundSql);
//Caution: this may take a long time!
executor.query(ms, parameter, rowBounds, resultHandler);
long endTime = System.currentTimeMillis();
long costTime = endTime - startTime;
log.info("\n Time taken to execute SQL: {}ms \nExecute SQL:\n {}\n", costTime, printSql);
} catch (Exception exception) {
log.error("Get sql exception", exception);
}
}
private static String generateSql(MappedStatement statement, Object parameter, BoundSql boundSql) {
Configuration configuration = statement.getConfiguration();
Object parameterObject = boundSql.getParameterObject();
List<ParameterMapping> params = boundSql.getParameterMappings();
String sql = boundSql.getSql();
sql = sql.replaceAll("[\\s]+", " ");
if (!ObjectUtils.isEmpty(params) && !ObjectUtils.isEmpty(parameterObject)) {
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(parameterObject)));
} else {
for (ParameterMapping param : params) {
String propertyName = param.getProperty();
MetaObject metaObject = configuration.newMetaObject(parameterObject);
if (metaObject.hasGetter(propertyName)) {
Object obj = metaObject.getValue(propertyName);
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
} else if (boundSql.hasAdditionalParameter(propertyName)) {
Object obj = boundSql.getAdditionalParameter(propertyName);
sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj)));
} else {
sql = sql.replaceFirst("\\?", "missing");
}
}
}
}
return sql;
}
private static String getParameterValue(Object object) {
String value = "";
if (object instanceof String) {
value = "'" + object.toString() + "'";
} else if (object instanceof Date) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
value = "'" + format.format((Date) object) + "'";
} else if (object instanceof LocalDateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
value = "'" + ((LocalDateTime) object).format(formatter) + "'";
} else if (!ObjectUtils.isEmpty(object)) {
value = object.toString();
}
return value;
}
}
2.注入拦截器
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new MyBatisPlusSqlInterceptor());
...
return interceptor;
}
}