完整的 Spring Boot + Hibernate/JPA + P6Spy 配置指南
以下是完整的配置步骤,确保 P6Spy 能正确显示带有真实参数的 SQL 语句。
1. 完整依赖配置
Maven (pom.xml
)
xml
<dependencies><!-- Spring Boot Starter Data JPA --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- 数据库驱动 (以MySQL为例) --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- P6Spy 核心依赖 --><dependency><groupId>p6spy</groupId><artifactId>p6spy</artifactId><version>3.9.1</version></dependency><!-- 可选:如果你使用HikariCP连接池 --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId></dependency> </dependencies>
2. 完整的 application.yml
配置
yaml
spring:datasource:url: jdbc:p6spy:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTCusername: your_usernamepassword: your_passworddriver-class-name: com.p6spy.engine.spy.P6SpyDriverhikari:# HikariCP 配置pool-name: SpringBootHikariCPauto-commit: falseconnection-timeout: 30000maximum-pool-size: 20minimum-idle: 5max-lifetime: 1800000jpa:show-sql: false # 禁用原生Hibernate的SQL日志properties:hibernate:format_sql: trueuse_sql_comments: true# 禁用Hibernate的统计信息(避免与P6Spy冲突)generate_statistics: false# 使用P6Spy作为SQL日志记录器session_factory.statement_inspector: com.p6spy.engine.spy.P6SpyLoggerlogging:level:com.p6spy: DEBUG # 设置P6Spy日志级别
3. spy.properties
完整配置
在 src/main/resources
下创建:
properties
# 基本模块配置 module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory# 日志输出方式(使用SLF4J) appender=com.p6spy.engine.spy.appender.Slf4JLogger# 自定义日志格式(显示时间、执行时间、SQL) logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat customLogMessageFormat=%(executionTime) ms | SQL: %(sqlSingleLine)# 是否显示二进制字段 excludebinary=true# 过滤配置 #filter=false #exclude=QRTZ_* # 排除特定表# 批处理配置 executionThreshold=100 # 只记录执行超过100ms的SQL# 日期格式 dateformat=yyyy-MM-dd HH:mm:ss# 是否记录JDBC连接事件 logConnect=false# 是否记录提交事件 logCommit=false# 是否记录回滚事件 logRollback=false
4. 高级自定义配置(可选)
自定义日志格式类
java
package com.yourpackage.config;import com.p6spy.engine.spy.appender.MessageFormattingStrategy; import org.hibernate.engine.jdbc.internal.BasicFormatterImpl; import org.hibernate.engine.jdbc.internal.Formatter;public class PrettySqlFormat implements MessageFormattingStrategy {private static final Formatter SQL_FORMATTER = new BasicFormatterImpl();@Overridepublic String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {if (sql.isEmpty()) {return "";}String formattedSql = SQL_FORMATTER.format(sql).replace("\n", "\n\t");return String.format("Hibernate: %s %s {elapsed: %dms}",category,formattedSql,elapsed);} }
然后在 spy.properties
中引用:
properties
logMessageFormat=com.yourpackage.config.PrettySqlFormat
5. 验证配置是否生效
启动应用后,你应该能在日志中看到类似这样的输出:
text
15 ms | SQL: select * from user where id=1 and name='John'
而不是预处理语句:
text
select * from user where id=? and name=?
常见问题解决方案
参数没有被替换:
确保
spy.properties
文件在 classpath 根目录检查 JDBC URL 是否正确添加了
jdbc:p6spy:
前缀确保没有其他日志框架覆盖了 P6Spy 的输出
与 HikariCP 的兼容性问题:
确保 HikariCP 的配置正确:
yaml
spring:datasource:hikari:driver-class-name: com.p6spy.engine.spy.P6SpyDriverjdbc-url: jdbc:p6spy:mysql://localhost:3306/your_database
性能问题:
生产环境中可以设置
filter=true
并排除不重要的表增加
executionThreshold
值只记录慢查询
多数据源配置:
每个数据源都需要单独配置 P6Spy:
java
@Bean @Primary public DataSource primaryDataSource() {return DataSourceBuilder.create().url("jdbc:p6spy:mysql://host1/db").driverClassName("com.p6spy.engine.spy.P6SpyDriver").build(); }@Bean public DataSource secondaryDataSource() {return DataSourceBuilder.create().url("jdbc:p6spy:mysql://host2/db").driverClassName("com.p6spy.engine.spy.P6SpyDriver").build(); }
这样配置后,P6Spy 将能完整记录所有 SQL 语句及其真实参数值,便于开发和调试。