p6spy 配置及执行流程
配置
- 引入 maven 依赖
1
2
3
4
5<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>${p6spy.version}</version>
</dependency> - 配置 spy.properties 文件
1
2
3
4
5
6logMessageFormat=com.xxx.P6SpyLogger
appender=com.p6spy.engine.spy.appender.Slf4JLogger
dateformat=yyyy-MM-dd HH:mm:ss
# 过滤 druid 空闲检测语句
filter=true
exclude=DUAL - 自定义日志格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class P6SpyLogger implements MessageFormattingStrategy {
/**
* @param connectionId: 连接ID
* @param now: 当前时间
* @param elapsed: 花费时间
* @param category: 类别
* @param prepared: 预编译SQL
* @param sql: 最终执行的SQL
* @param url: 数据库连接地址
* @return 格式化日志结果
*/
public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
if (StrUtil.isBlank(sql) || "SELECT 1 FROM DUAL".equals(sql)) {
return "";
} else {
return " took:" + elapsed + " ms" + " | sql:" + sql.replaceAll("[\\s]+", " ") + "\n";
}
}
}
流程
配置 p6spy 的 mysql 驱动:com.p6spy.engine.spy.P6SpyDriver

通过 P6SpyDriver 创建 Connection,返回 com.p6spy.engine.wrapper.ConnectionWrapper 包装真正的 Connection


ConnectionWrapper 重写 createStatement(),返回 com.p6spy.engine.wrapper.StatementWrapper 包装真正的 Statement


StatementWrapper 重写 executeQuery(),在执行 sql 之后调用 JdbcEventListener 的 onAfterExecuteQuery()


最终执行子类 LoggingEventListener 的 onAfterAnyExecute(),调用 P6Logger 的 logSQL()


