diff --git a/src/main/angular b/src/main/angular index b06591f5..e77afb17 160000 --- a/src/main/angular +++ b/src/main/angular @@ -1 +1 @@ -Subproject commit b06591f5266736a8546bf0eae85c83951055ecf4 +Subproject commit e77afb178acf01819e47be805249d8c8cfcea089 diff --git a/src/main/java/org/daming/hoteler/config/MyBatisConfig.java b/src/main/java/org/daming/hoteler/config/MyBatisConfig.java new file mode 100644 index 00000000..05d507c5 --- /dev/null +++ b/src/main/java/org/daming/hoteler/config/MyBatisConfig.java @@ -0,0 +1,20 @@ +package org.daming.hoteler.config; + +import org.daming.hoteler.repository.interceptors.SqlInterceptor; +import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author gming001 + * @version 2024-06-16 10:01 + */ +@Configuration +public class MyBatisConfig { + + @Bean + public ConfigurationCustomizer mybatisConfigurationCustomizer() { + return configuration -> configuration.addInterceptor(new SqlInterceptor()); + } + +} diff --git a/src/main/java/org/daming/hoteler/repository/interceptors/SqlInterceptor.java b/src/main/java/org/daming/hoteler/repository/interceptors/SqlInterceptor.java new file mode 100644 index 00000000..aadd1e15 --- /dev/null +++ b/src/main/java/org/daming/hoteler/repository/interceptors/SqlInterceptor.java @@ -0,0 +1,119 @@ +package org.daming.hoteler.repository.interceptors; + +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.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.daming.hoteler.base.logger.SqlLoggerUtil; +import org.springframework.util.ObjectUtils; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +/** + * @author gming001 + * @version 2024-06-16 09:29 + */ +@Intercepts({ + @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }), + @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class }), + @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class} ) +}) +public class SqlInterceptor implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + var in = Instant.now(); + String sql = ""; + Object[] params = new Object[0]; + try { + Object proceed = invocation.proceed(); + + return proceed; + } catch (Exception ex) { + if (ObjectUtils.isEmpty(sql)) { + sql = this.getSqlStatement(invocation); + } + if (ObjectUtils.isEmpty(params)) { + params = this.getSqlStatementParameter(invocation); + } + SqlLoggerUtil.logSqlException(sql, params, ex); + throw ex; + } finally { + if (ObjectUtils.isEmpty(sql)) { + sql = this.getSqlStatement(invocation); + } + if (ObjectUtils.isEmpty(params)) { + params = this.getSqlStatementParameter(invocation); + } + SqlLoggerUtil.logSql(sql, params, Duration.between(in, Instant.now())); + } + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target,this); + } + + private String getSqlStatement(Invocation invocation) { + var statement = (MappedStatement)invocation.getArgs()[0]; + Object parameter = null; + if (invocation.getArgs().length > 1) { + parameter = invocation.getArgs()[1]; + } + var boundSql = statement.getBoundSql(parameter); + var sql = boundSql.getSql(); + sql = sql.replaceAll("[\\s]+", " "); + + return sql; + } + + private Object[] getSqlStatementParameter(Invocation invocation) { + var statement = (MappedStatement)invocation.getArgs()[0]; + Object parameter = null; + if (invocation.getArgs().length > 1) { + parameter = invocation.getArgs()[1]; + } + var configuration = statement.getConfiguration(); + var boundSql = statement.getBoundSql(parameter); + Object parameterObject = boundSql.getParameterObject(); + List params = boundSql.getParameterMappings(); + List args = new ArrayList<>(); + if (!ObjectUtils.isEmpty(params) && !ObjectUtils.isEmpty(parameterObject)) { + var typeHandlerRegistry = configuration.getTypeHandlerRegistry(); + if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { + if (parameterObject instanceof Object[]) { + Stream.of(parameterObject).forEach(args::add); + } else { + args.add(parameterObject); + } + + } else { + for (ParameterMapping param : params) { + var propertyName = param.getProperty(); + var metaObject = configuration.newMetaObject(parameterObject); + if (metaObject.hasGetter(propertyName)) { + Object obj = metaObject.getValue(propertyName); + args.add(obj); + } else if (boundSql.hasAdditionalParameter(propertyName)) { + Object obj = boundSql.getAdditionalParameter(propertyName); + args.add(obj); + } + } + } + } + + return args.toArray(); + } +} diff --git a/src/main/java/org/daming/hoteler/utils/IpUtils.java b/src/main/java/org/daming/hoteler/utils/IpUtils.java index e2d1c360..1f505215 100644 --- a/src/main/java/org/daming/hoteler/utils/IpUtils.java +++ b/src/main/java/org/daming/hoteler/utils/IpUtils.java @@ -217,6 +217,6 @@ public static String getMultistageReverseProxyIp(String ip) { * @return 是否未知 */ public static boolean isUnknown(String checkString) { - return checkString == null || checkString.length() == 0 || "unknown".equalsIgnoreCase(checkString); + return checkString == null || checkString.isEmpty() || "unknown".equalsIgnoreCase(checkString); } }