|
@@ -1,11 +1,15 @@
|
|
|
package com.ruoyi.framework.mybatis.interceptor;
|
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alibaba.druid.DbType;
|
|
|
+import com.alibaba.druid.sql.SQLUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.ibatis.executor.statement.StatementHandler;
|
|
|
import org.apache.ibatis.mapping.BoundSql;
|
|
|
import org.apache.ibatis.mapping.MappedStatement;
|
|
|
-import org.apache.ibatis.mapping.ParameterMapping;
|
|
|
import org.apache.ibatis.mapping.ParameterMode;
|
|
|
import org.apache.ibatis.plugin.Interceptor;
|
|
|
import org.apache.ibatis.plugin.Intercepts;
|
|
@@ -16,15 +20,13 @@ import org.apache.ibatis.reflection.SystemMetaObject;
|
|
|
import org.apache.ibatis.session.Configuration;
|
|
|
import org.apache.ibatis.session.ResultHandler;
|
|
|
import org.apache.ibatis.type.TypeHandlerRegistry;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.context.annotation.Profile;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.sql.Statement;
|
|
|
-import java.text.DateFormat;
|
|
|
-import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
-import java.util.Locale;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 打印执行的sql日志
|
|
@@ -34,18 +36,15 @@ import java.util.Locale;
|
|
|
@Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
|
|
|
@Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})
|
|
|
})
|
|
|
+@Profile("dev")
|
|
|
@Slf4j
|
|
|
@Component
|
|
|
public class SqlLogInterceptor implements Interceptor {
|
|
|
|
|
|
- @Value("${spring.profiles.active}")
|
|
|
- private String active;
|
|
|
+ private final SQLUtils.FormatOption FORMAT_OPTION = new SQLUtils.FormatOption(false, false);
|
|
|
|
|
|
@Override
|
|
|
public Object intercept(Invocation invocation) throws Throwable {
|
|
|
- if (!"dev".equals(active)) {
|
|
|
- return invocation.proceed();
|
|
|
- }
|
|
|
|
|
|
long start = System.currentTimeMillis();
|
|
|
Object result = invocation.proceed();
|
|
@@ -53,48 +52,42 @@ public class SqlLogInterceptor implements Interceptor {
|
|
|
|
|
|
StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());
|
|
|
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
|
|
|
- MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
|
|
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
|
|
|
- String sql = boundSql.getSql().replaceAll("\\s+", " ");
|
|
|
|
|
|
- List<ParameterMapping> parameterMappings = new ArrayList<>(boundSql.getParameterMappings());
|
|
|
Object parameterObject = boundSql.getParameterObject();
|
|
|
- if (parameterMappings.isEmpty() && parameterObject == null) {
|
|
|
+ if (parameterObject == null) {
|
|
|
+ log.error("parameterObject is null");
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
|
|
|
Configuration configuration = mappedStatement.getConfiguration();
|
|
|
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
|
|
+ MetaObject newMetaObject = configuration.newMetaObject(parameterObject);
|
|
|
|
|
|
- try {
|
|
|
- String parameter = "null";
|
|
|
- MetaObject newMetaObject = configuration.newMetaObject(parameterObject);
|
|
|
- for (ParameterMapping parameterMapping : parameterMappings) {
|
|
|
- if (parameterMapping.getMode() == ParameterMode.OUT) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- String propertyName = parameterMapping.getProperty();
|
|
|
- if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
|
|
|
- parameter = getParameterValue(parameterObject);
|
|
|
- } else if (newMetaObject.hasGetter(propertyName)) {
|
|
|
- parameter = getParameterValue(newMetaObject.getValue(propertyName));
|
|
|
- } else if (boundSql.hasAdditionalParameter(propertyName)) {
|
|
|
- parameter = getParameterValue(boundSql.getAdditionalParameter(propertyName));
|
|
|
- }
|
|
|
+ List<Object> parameters = boundSql.getParameterMappings().stream()
|
|
|
+ .filter(item -> ObjectUtil.notEqual(item.getMode(), ParameterMode.OUT))
|
|
|
+ .map(item -> {
|
|
|
+ String propertyName = item.getProperty();
|
|
|
+ if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
|
|
|
+ return getParameterValue(parameterObject);
|
|
|
+ } else if (newMetaObject.hasGetter(propertyName)) {
|
|
|
+ return getParameterValue(newMetaObject.getValue(propertyName));
|
|
|
+ } else if (boundSql.hasAdditionalParameter(propertyName)) {
|
|
|
+ return getParameterValue(boundSql.getAdditionalParameter(propertyName));
|
|
|
+ }
|
|
|
+ return StringPool.EMPTY;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
|
|
|
- sql = sql.replaceFirst("\\?", parameter);
|
|
|
- }
|
|
|
+ String sql = SQLUtils.format(boundSql.getSql(), DbType.mysql, parameters, FORMAT_OPTION);
|
|
|
|
|
|
- // 打印 sql
|
|
|
- log.info("\n==================== Sql Start ===================="
|
|
|
- + "\n mapper : {}"
|
|
|
- + "\n execute sql : {}"
|
|
|
- + "\n execute time : {} ms"
|
|
|
- + "\n==================== Sql End ====================\n",
|
|
|
- mappedStatement.getId(), sql, end - start);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error(String.format("intercept sql error: [%s]\r\n", sql), e);
|
|
|
- }
|
|
|
+ // 打印 sql
|
|
|
+ log.info("\n==================== Sql Start ===================="
|
|
|
+ + "\n mapper : {}"
|
|
|
+ + "\n execute sql : {}"
|
|
|
+ + "\n execute time : {}"
|
|
|
+ + "\n==================== Sql End ====================\n",
|
|
|
+ mappedStatement.getId(), sql, DateUtil.formatBetween(end - start));
|
|
|
|
|
|
return result;
|
|
|
}
|
|
@@ -105,21 +98,14 @@ public class SqlLogInterceptor implements Interceptor {
|
|
|
* @param obj Object类型参数
|
|
|
* @return 转换之后的参数
|
|
|
*/
|
|
|
- private String getParameterValue(Object obj) {
|
|
|
- String value;
|
|
|
- if (obj instanceof String) {
|
|
|
- value = "'" + obj + "'";
|
|
|
- } else if (obj instanceof Date) {
|
|
|
- DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
|
|
|
- value = "'" + formatter.format(new Date()) + "'";
|
|
|
- } else {
|
|
|
- if (obj != null) {
|
|
|
- value = obj.toString();
|
|
|
- } else {
|
|
|
- value = "";
|
|
|
- }
|
|
|
+ private Object getParameterValue(Object obj) {
|
|
|
+ if (obj == null) {
|
|
|
+ return StringPool.EMPTY;
|
|
|
+ }
|
|
|
+ if (obj instanceof Date) {
|
|
|
+ return DateUtil.formatDateTime((Date) obj);
|
|
|
}
|
|
|
- return value.replace("$", "\\$");
|
|
|
+ return obj;
|
|
|
}
|
|
|
|
|
|
}
|