Skip to content

Commit 83fc7e9

Browse files
committed
feat: 添加 Mybatis 拦截器,打印 sql
1 parent 2977c62 commit 83fc7e9

1 file changed

Lines changed: 121 additions & 0 deletions

File tree

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package top.cadecode.framework.handler;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.apache.ibatis.executor.Executor;
5+
import org.apache.ibatis.mapping.BoundSql;
6+
import org.apache.ibatis.mapping.MappedStatement;
7+
import org.apache.ibatis.mapping.ParameterMapping;
8+
import org.apache.ibatis.plugin.Interceptor;
9+
import org.apache.ibatis.plugin.Intercepts;
10+
import org.apache.ibatis.plugin.Invocation;
11+
import org.apache.ibatis.plugin.Signature;
12+
import org.apache.ibatis.reflection.MetaObject;
13+
import org.apache.ibatis.session.Configuration;
14+
import org.apache.ibatis.session.ResultHandler;
15+
import org.apache.ibatis.session.RowBounds;
16+
import org.apache.ibatis.type.TypeHandlerRegistry;
17+
import org.springframework.stereotype.Component;
18+
19+
import java.text.SimpleDateFormat;
20+
import java.util.Date;
21+
import java.util.List;
22+
23+
@Slf4j
24+
@Component
25+
@Intercepts({
26+
@Signature(type = Executor.class, method = "update",
27+
args = {MappedStatement.class, Object.class}),
28+
@Signature(type = Executor.class, method = "query",
29+
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
30+
public class MybatisSqlPrintingHandler implements Interceptor {
31+
32+
@Override
33+
public Object intercept(Invocation invocation) throws Throwable {
34+
// 获取 SQL 描述语句对象
35+
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
36+
// 获取参数
37+
Object parameter = null;
38+
if (invocation.getArgs().length > 1) {
39+
parameter = invocation.getArgs()[1];
40+
}
41+
// 获取 SQL Id
42+
String sqlId = mappedStatement.getId();
43+
// 获取 BoundSql 即 mybatis 封装的 SQL 对象
44+
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
45+
// 获取配置
46+
Configuration configuration = mappedStatement.getConfiguration();
47+
// 计时,执行
48+
long start = System.currentTimeMillis();
49+
Object returnValue = invocation.proceed();
50+
long time = System.currentTimeMillis() - start;
51+
// 打印 SQL
52+
showSql(configuration, boundSql, time, sqlId);
53+
return returnValue;
54+
}
55+
56+
/**
57+
* 处理 sql 中的字符
58+
*
59+
* @param configuration 配置对象
60+
* @param boundSql boundSql
61+
* @param time 用时
62+
* @param sqlId sql id
63+
*/
64+
private static void showSql(Configuration configuration, BoundSql boundSql, long time, String sqlId) {
65+
Object parameterObject = boundSql.getParameterObject();
66+
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
67+
// 替换空格、换行、tab缩进等
68+
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
69+
if (parameterMappings.size() > 0 && parameterObject != null) {
70+
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
71+
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
72+
sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
73+
} else {
74+
MetaObject metaObject = configuration.newMetaObject(parameterObject);
75+
for (ParameterMapping parameterMapping : parameterMappings) {
76+
String propertyName = parameterMapping.getProperty();
77+
if (metaObject.hasGetter(propertyName)) {
78+
Object obj = metaObject.getValue(propertyName);
79+
sql = sql.replaceFirst("\\?", getParameterValue(obj));
80+
} else if (boundSql.hasAdditionalParameter(propertyName)) {
81+
Object obj = boundSql.getAdditionalParameter(propertyName);
82+
sql = sql.replaceFirst("\\?", getParameterValue(obj));
83+
}
84+
}
85+
}
86+
}
87+
logs(time, sql, sqlId);
88+
}
89+
90+
/**
91+
* 对不同类型参数进行处理
92+
*
93+
* @param obj 参数
94+
* @return 处理后的参数
95+
*/
96+
private static String getParameterValue(Object obj) {
97+
String value;
98+
if (obj instanceof String) {
99+
value = "'" + obj + "'";
100+
} else if (obj instanceof Date) {
101+
// 处理日期类型
102+
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
103+
value = "'" + sdf.format(new Date()) + "'";
104+
} else {
105+
value = obj != null ? obj.toString() : "";
106+
}
107+
return value.replace("$", "\\$");
108+
}
109+
110+
/**
111+
* 打印 log
112+
*
113+
* @param time 用时
114+
* @param sql sql 语句
115+
* @param sqlId sql id
116+
*/
117+
private static void logs(long time, String sql, String sqlId) {
118+
log.info("sql 日志 => 执行 [" + sqlId + "] 用时 " + time + " 毫秒");
119+
log.info("sql 日志 <= 语句:" + sql);
120+
}
121+
}

0 commit comments

Comments
 (0)