摘要
本文介绍p6spy的使用场景及用法,对于IDE中直接查看sql耗时及拿取完整的sql语句很有帮助,让我们拿下它。
了解p6spy
p6spy是一个开源的JDBC驱动包装器,用于拦截和记录Java应用程序与数据库之间的SQL语句、参数、执行时间等。
作用
- SQL日志记录:捕获所有SQL语句及其参数,便于调试和验证ORM框架生成的SQL。
- 性能分析:记录每条SQL的执行耗时,定位慢查询。
- 慢查询检测:可配置慢查询阈值,自动标记耗时较长的SQL。
注意事项
- 依赖版本兼容性:确保P6Spy版本与数据库驱动版本兼容(如MySQL 8.x需要 P6Spy 3.9.x)。
- 若使用MyBatis Plus,需引入mybatis-plus-p6spy依赖。
- URL格式:数据库连接URL需以jdbc:p6spy:开头(如 jdbc:p6spy:mysql://...)。
- 配置文件位置:spy.properties文件需放在src/main/resources目录下。
- 性能开销:P6Spy 会增加少量性能开销(约 5%-10%),生产环境建议关闭或仅开启慢查询监控。
集成步骤
1)引入依赖 pom.xml
xml
<!-- sql性能分析插件 -->
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>
<!-- clickhouse -->
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.6.5</version>
</dependency>
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
2)可自定义日志解析方式 CustomP6SpyLogger.java
java
package org.coffeebeans.p6psy.config;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <li>ClassName: CustomP6SpyLogger </li>
* <li>Author: OakWang </li>
*/
public class CustomP6SpyLogger implements MessageFormattingStrategy {
// 匹配日期参数
private static final Pattern DATE_PATTERN = Pattern.compile("'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}\+\d{4}'");
// 使用 ANSI 颜色代码打印不同颜色
private static final String ANSI_RESET = "\u001B[0m"; //重置颜色
private static final String ANSI_YELLOW = "\u001B[33m"; //蓝色
private static final String ANSI_BLUE = "\u001B[34m"; //绿色
private static final String ANSI_GREEN = "\u001B[32m"; //粉色
@Override
public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
if (StringUtils.isBlank(sql)) {
return"";
}
// 只处理日期类型的参数
Matcher matcher = DATE_PATTERN.matcher(sql);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String dateStr = matcher.group();
dateStr = dateStr.substring(1, dateStr.length() - 1);
// 替换T为空格,移除时区信息
String formattedDate = dateStr.replace("T", " ").replaceAll("\+\d{4}$", "");
matcher.appendReplacement(sb, "'" + formattedDate + "'");
}
matcher.appendTail(sb);
return String.format("%s%s | %s执行时间:%d ms,%s执行SQL:%s%s",
ANSI_YELLOW, now, ANSI_BLUE, elapsed, ANSI_GREEN, sb, ANSI_RESET);
}
}
3)定义属性文件 spy.propertis
ini
# 定义模块列表,指定MyBatis Plus的日志工厂和P6Spy的中断检测工厂
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 设置日志消息格式类,使用自定义的P6Spy日志记录器
logMessageFormat=org.coffeebeans.p6psy.config.CustomP6SpyLogger
# 或者 自定义日志格式
# logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
# customLogMessageFormat=%(currentTime) | %(executionTime) ms | SQL: %(sqlSingleLine)
# 指定日志追加器,这里使用标准输出日志
appender=com.p6spy.engine.spy.appender.StdoutLogger
# 或者 慢查询日志输出到文件
# appender=com.p6spy.engine.spy.appender.FileLogger
# logfile=logs/p6spy.log
# append=true
# 启用前缀功能,以便在日志条目前添加特定前缀
useprefix=true
# 排除特定类别日志的输出,以减少不必要的日志信息
excludecategories=info,debug,result,commit,resultset
# 排除特定 SQL
exclude=SELECT 1
# 设置日期格式,用于日志条目的时间戳
dateformat=yyyy-MM-dd HH:mm:ss
# 慢查询检测(2秒以上标记为慢查询)
# 启用中断检测功能,以监控数据库操作的中断情况
outagedetection=true
# 设置中断检测间隔,每2秒检查一次数据库操作的中断情况
outagedetectioninterval=2
# 启用过滤功能,根据配置的规则过滤日志输出
filter=true
4)application.yml指定数据库连接驱动及url,以clickhouse为例
yaml
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
clickhouse:
# driverClassName: com.clickhouse.jdbc.ClickHouseDriver
# url: jdbc:clickhouse://192.168.233.129:8123/default
driverClassName: com.p6spy.engine.spy.P6SpyDriver #使用P6Spy驱动
url: jdbc:p6spy:clickhouse://192.168.233.129:8123/default #使用P6Spy的url方式
username: default
password: 123456
initialSize: 10
maxActive: 100
minIdle: 10
maxWait: 6000
5)测试sql打印(省略了集成orm那一套查询细节)

总结
以上我们了解了p6spy的基本作用及使用方式,一般的mybatis/plus打印的sql大概是需要自己拼接的?占位符,这里我们利用第三方工具p6psy就能直接看到sql耗时,且可直接拷贝sql出来运行。
关注公众号:咖啡Beans
在这里,我们专注于软件技术的交流与成长,分享开发心得与笔记,涵盖编程、AI、资讯、面试等多个领域。无论是前沿科技的探索,还是实用技巧的总结,我们都致力于为大家呈现有价值的内容。期待与你共同进步,开启技术之旅。