springboot项目整合p6spy框架,实现日志打印SQL明细(包括SQL语句和参数)
1.application.yml配置文件
# 项目相关配置
admin:# 名称name: admin-project# 版本version: 3.4.0# 版权年份copyrightYear: 2023# 实例演示开关demoEnabled: true# 文件路径 示例( Windows配置D:/XXXX/uploadPath,Linux配置 /home/XXXX/uploadPath)profile: D:/home/XXXX/uploadPath/# 获取ip地址开关addressEnabled: false# 验证码类型 math 数组计算 char 字符验证captchaType: math# 开发环境配置
server:# 服务器的HTTP端口,默认为8080port: 7070servlet:# 应用的访问路径, 只有在使用外部 tmmcat、东方通中部署时有用,默认不填路径##context-path: /XXXXapi 后面填路径时,前台vue请求后台时,一定要拼接这个路径,不然接口会404context-path: /XXXXapitomcat:# tomcat的URI编码uri-encoding: UTF-8# tomcat最大线程数,默认为200max-threads: 800# Tomcat启动初始化的线程数,默认值25min-spare-threads: 30# 日志配置
logging:level:com.admin: info # 1. 项目业务包:从debug降为info,减少非必要业务DEBUG日志org.springframework: warn # 保持不变(已过滤Spring的DEBUG)com.admin.plus.dao: info # 2. MyBatis-Plus的DAO层:从debug降为info,关闭DAO层DEBUGorg.mybatis: info # 3. MyBatis核心包:从debug降为info,彻底关闭MyBatis的DEBUG日志(如SqlSessionUtils日志)# Spring配置
spring:# 资源信息messages:# 国际化资源文件路径basename: i18n/messagesprofiles:active: druid# 文件上传servlet:multipart:# 单个文件大小max-file-size: 10MB# 设置总上传的文件大小max-request-size: 20MB# 服务模块devtools:restart:# 热部署开关enabled: truemain:allow-bean-definition-overriding: true# token配置
token:# 令牌自定义标识header: Authorization# 令牌密钥secret: abcdefghijklmnopqrstuvwxyz# 令牌有效期(默认30分钟)expireTime: 30# MyBatis配置
mybatis-plus:# 搜索指定包别名typeAliasesPackage: com.admin.**.domain# 配置mapper的扫描,找到所有的mapper.xml映射文件mapperLocations: classpath*:mapper/**/*Mapper.xml# 加载全局的配置文件configLocation: classpath:mybatis/mybatis-config.xmllog-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:# 更新策略:仅当字段值不为 null 且不为空字符串时才更新update-strategy: NOT_EMPTY# Swagger配置
swagger:# 是否开启swaggerenabled: true# 请求前缀pathMapping: /# 防止XSS攻击
xss:# 过滤开关enabled: true# 排除链接(多个用逗号分隔)excludes: /system/notice/*# 匹配链接urlPatterns: /system/*,/monitor/*,/tool/*# redis 中间件配置
# redis:
# # 地址
# host: localhost
# # 端口,默认为6379
# port: 6379
# # 数据库索引
# database: 0
# # 密码
# password:
# # 连接超时时间
# timeout: 10s
# lettuce:
# pool:
# # 连接池中的最小空闲连接
# min-idle: 0
# # 连接池中的最大空闲连接
# max-idle: 8
# # 连接池的最大数据库连接数
# max-active: 8
# # #连接池最大阻塞等待时间(使用负值表示没有限制)
# max-wait: -1ms#文件预览相关配置
#preview:
# serverIp: 127.0.0.1
# serverPort: 8012
#/home/XXXX/uploadPath/ 是文件上传的物理路径
upload:#rootUploadPath: /home/XXXX/uploadPath/rootUploadPath: D:/home/XXXX/uploadPath/# BeetlSQL配置
beetlsql:# 数据库类型dbStyle: mysql #达梦数据库# mapper接口包路径daoPackage: com.admin.business.beetlMapper# 是否开启调试debug: true# 命名转换 (数据库下划线转Java驼峰)nameConversion: org.beetl.sql.core.UnderlinedNameConversion
2.application-druid.yml
spring:datasource:type: com.alibaba.druid.pool.DruidDataSource#driverClassName: dm.jdbc.driver.DmDriverdruid:# 主库数据源master:# XXXXXurl: jdbc:p6spy:dm://127.0.0.1:5237/XXXXX?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: XXXXXpassword: 123456789driverClassName: com.p6spy.engine.spy.P6SpyDriver#从库数据源slave:# 从数据源开关/默认关闭enabled: trueurl: jdbc:oracle:thin:@127.0.0.1:1521/XXXXXusername: XXXXXpassword: XXXXXdriverClassName: oracle.jdbc.driver.OracleDriver# 初始连接数initialSize: 5# 最小连接池数量minIdle: 10# 最大连接池数量maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效validationQuery: SELECT 1 FROM DUALtestWhileIdle: truetestOnBorrow: falsetestOnReturn: falsewebStatFilter:enabled: truestatViewServlet:enabled: true# 设置白名单,不填则允许所有访问allow:url-pattern: /druid/*# 控制台管理用户名和密码login-username:login-password:filter:stat:enabled: true# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: true
3.spy.properties
# 开启模块sql记录和长时sql记录
module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自己编写格式类
logMessageFormat = com.admin.web.P6spySqlFormatConfig# 通过配置进行格式设置
#logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
# 自定义sql输出格式
#customLogMessageFormat=%(currentTime) | TIME\uFF1A %(executionTime) ms | SQL\uFF1A %(sql)# 日志输出方式(输出到控制台)
appender=com.p6spy.engine.spy.appender.StdoutLogger
#appender=com.p6spy.engine.spy.appender.Slf4JLoggerexcludecategories=debug, info,debug,result,resultset,commit, rollback
deregisterdrivers=true
dateformat=yyyy-MM-dd HH:mm:ss
driverlist=com.mysql.cj.jdbc.Driver
# 开启长时sql记录
outagedetection=true
# 触发长时记录时限
outagedetectioninterval=2# 开启过滤功能
filter=true
# 过滤掉所有涉及Quartz表的SQL(QRTZ_开头的表)
exclude = .*QRTZ_.*
.
4.maven依赖
<!-- sql 打印 --><dependency><groupId>p6spy</groupId><artifactId>p6spy</artifactId><version>3.8.5</version></dependency>
5.P6spySqlFormatConfig.java
package com.admin.web;import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**** @author wangwei* @date 2025-09-266 13:29:00*/
public class P6spySqlFormatConfig implements MessageFormattingStrategy {// 用于匹配SQL中的参数占位符(?)和数字参数private static final Pattern PARAM_PATTERN = Pattern.compile("\\?(?=\\s|,|\\)|$)");@Overridepublic String formatMessage(int connectionId, String now, long elapsed, String category,String prepared, String sql, String url) {// 如果SQL为空,直接返回if (sql == null || sql.trim().isEmpty()) {return "";}// 处理SQL参数,为数字和字符串参数添加单引号String formattedSql = addQuotesToParameters(sql);// 格式化输出日志,包含时间、执行时长和处理后的SQLreturn String.format("[%s] | 耗时:%d ms | SQL:%s",now, elapsed, formattedSql);}/*** 为SQL中的参数添加单引号*/private String addQuotesToParameters(String sql) {// 这里使用简单的正则处理,实际场景可能需要更复杂的解析// 注意:这种方式适用于大多数简单场景,复杂SQL可能需要调整Matcher matcher = PARAM_PATTERN.matcher(sql);StringBuffer sb = new StringBuffer();while (matcher.find()) {// 替换?为带单引号的参数占位符,实际参数值会被包裹matcher.appendReplacement(sb, "'?'");}matcher.appendTail(sb);return sb.toString();}
}
6.效果