com.pig4cloud
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/config/PigxMybatisProperties.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/config/PigxMybatisProperties.java
new file mode 100644
index 000000000..43f789ace
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/config/PigxMybatisProperties.java
@@ -0,0 +1,23 @@
+package com.pig4cloud.pigx.common.data.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+
+/**
+ * Mybatis 配置
+ *
+ * @author lengleng
+ * @date 2021/6/3
+ */
+@Data
+@RefreshScope
+@ConfigurationProperties("pigx.mybatis")
+public class PigxMybatisProperties {
+
+ /**
+ * 是否打印可执行 sql
+ */
+ private boolean showSql = true;
+
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/DruidSqlLogFilter.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/DruidSqlLogFilter.java
new file mode 100644
index 000000000..8d1cd3a43
--- /dev/null
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/DruidSqlLogFilter.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pig4cloud.pigx.common.data.mybatis;
+
+import com.alibaba.druid.DbType;
+import com.alibaba.druid.filter.FilterChain;
+import com.alibaba.druid.filter.FilterEventAdapter;
+import com.alibaba.druid.proxy.jdbc.JdbcParameter;
+import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
+import com.alibaba.druid.proxy.jdbc.StatementProxy;
+import com.alibaba.druid.sql.SQLUtils;
+import com.alibaba.druid.util.StringUtils;
+import com.pig4cloud.pigx.common.data.config.PigxMybatisProperties;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.sql.SQLException;
+import java.time.temporal.TemporalAccessor;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 打印可执行的 sql 日志
+ *
+ *
+ * 参考:https://jfinal.com/share/2204
+ *
+ *
+ * @author L.cm
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class DruidSqlLogFilter extends FilterEventAdapter {
+
+ private static final SQLUtils.FormatOption FORMAT_OPTION = new SQLUtils.FormatOption(false, false);
+
+ private final PigxMybatisProperties properties;
+
+ @Override
+ protected void statementExecuteBefore(StatementProxy statement, String sql) {
+ statement.setLastExecuteStartNano();
+ }
+
+ @Override
+ protected void statementExecuteBatchBefore(StatementProxy statement) {
+ statement.setLastExecuteStartNano();
+ }
+
+ @Override
+ protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {
+ statement.setLastExecuteStartNano();
+ }
+
+ @Override
+ protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {
+ statement.setLastExecuteStartNano();
+ }
+
+ @Override
+ protected void statementExecuteAfter(StatementProxy statement, String sql, boolean firstResult) {
+ statement.setLastExecuteTimeNano();
+ }
+
+ @Override
+ protected void statementExecuteBatchAfter(StatementProxy statement, int[] result) {
+ statement.setLastExecuteTimeNano();
+ }
+
+ @Override
+ protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {
+ statement.setLastExecuteTimeNano();
+ }
+
+ @Override
+ protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {
+ statement.setLastExecuteTimeNano();
+ }
+
+ @Override
+ public void statement_close(FilterChain chain, StatementProxy statement) throws SQLException {
+ // 先调用父类关闭 statement
+ super.statement_close(chain, statement);
+ // 支持动态开启
+ if (!properties.isShowSql()) {
+ return;
+ }
+
+ // 是否开启调试
+ if (!log.isInfoEnabled()) {
+ return;
+ }
+
+ // 打印可执行的 sql
+ String sql = statement.getBatchSql();
+ // sql 为空直接返回
+ if (StringUtils.isEmpty(sql)) {
+ return;
+ }
+ int parametersSize = statement.getParametersSize();
+ List parameters = new ArrayList<>(parametersSize);
+ for (int i = 0; i < parametersSize; ++i) {
+ // 转换参数,处理 java8 时间
+ parameters.add(getJdbcParameter(statement.getParameter(i)));
+ }
+ String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
+ String formattedSql = SQLUtils.format(sql, DbType.of(dbType), parameters, FORMAT_OPTION);
+ printSql(formattedSql, statement);
+ }
+
+ private static Object getJdbcParameter(JdbcParameter jdbcParam) {
+ if (jdbcParam == null) {
+ return null;
+ }
+ Object value = jdbcParam.getValue();
+ // 处理 java8 时间
+ if (value instanceof TemporalAccessor) {
+ return value.toString();
+ }
+ return value;
+ }
+
+ private static void printSql(String sql, StatementProxy statement) {
+ // 打印 sql
+ String sqlLogger = "\n\n======= Sql Logger ======================" + "\n{}"
+ + "\n======= Sql Execute Time: {} =======\n";
+ log.info(sqlLogger, sql.trim(), format(statement.getLastExecuteTimeNano()));
+ }
+
+ /**
+ * 格式化执行时间,单位为 ms 和 s,保留三位小数
+ * @param nanos 纳秒
+ * @return 格式化后的时间
+ */
+ private static String format(long nanos) {
+ if (nanos < 1) {
+ return "0ms";
+ }
+ double millis = (double) nanos / (1000 * 1000);
+ // 不够 1 ms,最小单位为 ms
+ if (millis > 1000) {
+ return String.format("%.3fs", millis / 1000);
+ }
+ else {
+ return String.format("%.3fms", millis);
+ }
+ }
+
+}
diff --git a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java
index 160efafd4..be4e80d01 100644
--- a/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java
+++ b/pigx-common/pigx-common-data/src/main/java/com/pig4cloud/pigx/common/data/mybatis/MybatisPlusConfiguration.java
@@ -17,13 +17,10 @@
package com.pig4cloud.pigx.common.data.mybatis;
-import java.util.List;
-
-import javax.sql.DataSource;
-
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
+import com.pig4cloud.pigx.common.data.config.PigxMybatisProperties;
import com.pig4cloud.pigx.common.data.datascope.DataScopeHandle;
import com.pig4cloud.pigx.common.data.datascope.DataScopeInnerInterceptor;
import com.pig4cloud.pigx.common.data.datascope.DataScopeSqlInjector;
@@ -36,11 +33,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import javax.sql.DataSource;
+import java.util.List;
+
/**
* @author lengleng
* @date 2020-02-08
@@ -48,6 +49,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ConditionalOnBean(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
+@EnableConfigurationProperties(PigxMybatisProperties.class)
public class MybatisPlusConfiguration implements WebMvcConfigurer {
/**
@@ -110,4 +112,13 @@ public class MybatisPlusConfiguration implements WebMvcConfigurer {
return new DataScopeSqlInjector();
}
+ /**
+ * SQL 日志格式化
+ * @return DruidSqlLogFilter
+ */
+ @Bean
+ public DruidSqlLogFilter sqlLogFilter(PigxMybatisProperties properties) {
+ return new DruidSqlLogFilter(properties);
+ }
+
}