前言
在開發基于Spring Boot和MyBatis Plus的項目時,日志功能是調試和優化SQL查詢的核心工具。通過合理配置日志輸出,開發者可以直觀查看生成的SQL語句、執行時間、參數值以及潛在的性能瓶頸。
一、MyBatis Plus日志配置
1.1 基礎配置:直接輸出SQL日志
1.1.1 配置log-impl
MyBatis Plus提供了一個簡單的配置項log-impl
,可將SQL日志直接輸出到控制臺。
配置方式(application.yml):
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
效果示例:
DEBUG [http-nio-8080-exec-1] c.b.mp.mapper.UserMapper.selectList - ==> Preparing: SELECT * FROM user WHERE age > ?
DEBUG [http-nio-8080-exec-1] c.b.mp.mapper.UserMapper.selectList - ==> Parameters: 18(Integer)
DEBUG [http-nio-8080-exec-1] c.b.mp.mapper.UserMapper.selectList - <== Total: 5
說明:
==> Preparing
: 顯示SQL語句(占位符形式)。==> Parameters
: 顯示參數值。<== Total
: 顯示查詢結果數量。
1.1.2 通過日志框架調整日志級別
若項目使用Logback或Log4j2等日志框架,可通過設置包路徑的日志級別來控制輸出。
配置方式(application.yml):
logging:level:com.example.mapper: DEBUG
效果:
- 輸出與
log-impl
類似的SQL日志,但需依賴日志框架的配置。
1.2 高級配置:自定義日志格式
1.2.1 使用自定義Log
實現類
通過實現org.apache.ibatis.logging.Log
接口,開發者可以自定義日志格式。
步驟:
- 創建自定義
Log
類:
public class CustomLogger implements Log {@Overridepublic boolean isDebugEnabled() { return true; }@Overridepublic void debug(String s) { System.out.println("[DEBUG] " + s); }// 其他方法實現...
}
- 配置
log-impl
:
mybatis-plus:configuration:log-impl: com.example.CustomLogger
效果示例:
[DEBUG] [SQL_EXECUTE] SELECT id, name, age FROM user WHERE age > 18
[DEBUG] [RESULT] 5 rows affected
二、P6Spy日志配置:更詳細的SQL監控
2.1 為什么使用P6Spy?
P6Spy是一個輕量級的數據庫訪問監控工具,支持以下功能:
- 完整SQL輸出:替換占位符
?
為實際參數值。 - 慢SQL檢測:記錄執行時間超過閾值的SQL。
- 多格式日志:支持控制臺、文件、日志框架(如SLF4J)輸出。
2.2 配置步驟
2.2.1 添加依賴
在pom.xml
中引入P6Spy依賴:
<dependency><groupId>p6spy</groupId><artifactId>p6spy</artifactId><version>3.9.1</version>
</dependency>
2.2.2 修改數據源配置
將JDBC驅動替換為P6Spy代理驅動,并調整URL格式。
application.yml配置示例:
spring:datasource:driver-class-name: com.p6spy.engine.spy.P6SpyDriverurl: jdbc:p6spy:mysql://localhost:3306/demousername: rootpassword: root
2.2.3 創建spy.properties
文件
在src/main/resources
目錄下創建spy.properties
,配置P6Spy行為:
# 模塊列表
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory# 自定義日志格式
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger# 日志輸出到控制臺
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger# 取消JDBC驅動注冊
deregisterdrivers=true# 使用前綴
useprefix=true# 排除的日志類別
excludecategories=info,debug,result,commit,resultset# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss# 實際驅動列表
driverlist=com.mysql.cj.jdbc.Driver# 開啟慢SQL記錄
outagedetection=true# 慢SQL記錄標準(單位:秒)
outagedetectioninterval=2# 過濾特定表的SQL
filter=true
exclude=flw_.+
關鍵配置說明:
excludecategories
:排除冗余日志(如result
、commit
)。outagedetectioninterval
:慢SQL閾值(單位:秒)。exclude=flw_.+
:正則表達式,過濾表名以flw_
開頭的SQL。
2.2.4 控制臺輸出示例
[2025-06-24 21:25:47] [main] [INFO] Execute SQL: SELECT id, name, age FROM user WHERE age > 18
[2025-06-24 21:25:47] [main] [INFO] Parameters: 18
[2025-06-24 21:25:47] [main] [INFO] Elapsed Time: 12ms
2.2.5 慢SQL監控輸出
當SQL執行時間超過2秒時,P6Spy會標記為慢SQL:
[2025-06-24 21:25:47] [main] [WARN] Outage Detected: SQL execution took 3000ms
[2025-06-24 21:25:47] [main] [INFO] Slow SQL: SELECT * FROM large_table WHERE condition = 'value'
三、生產環境注意事項
3.1 性能影響
- 控制臺日志:頻繁輸出SQL日志會增加I/O開銷,建議僅在開發環境啟用。
- 文件日志:若需記錄日志,使用文件輸出(如
FileLogger
)并定期歸檔。
3.2 安全性
- 敏感數據:避免在日志中記錄用戶密碼、信用卡號等敏感信息。
- 日志過濾:通過
exclude
配置過濾業務無關的表(如流程引擎表flw_*
)。
3.3 兼容性
- 驅動版本:確保
driverlist
中指定的驅動與實際數據庫版本一致。 - P6Spy版本:推薦使用3.9.x及以上版本以獲得最佳兼容性。
四、進階優化:自定義日志格式
4.1 實現MessageFormattingStrategy
接口
通過自定義日志格式化策略,開發者可以靈活控制日志輸出內容。
示例代碼:
public class CustomP6SpyLogger implements MessageFormattingStrategy {@Overridepublic String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql) {return String.format("[%.3fms] %s", elapsed / 1000.0, sql);}
}
配置spy.properties
:
logMessageFormat=com.example.CustomP6SpyLogger
效果示例:
[0.012ms] SELECT id, name, age FROM user WHERE age > 18
五、總結
通過合理配置MyBatis Plus和P6Spy,開發者可以高效監控SQL執行情況,快速定位性能瓶頸。以下是關鍵建議:
- 開發環境:啟用
log-impl
或P6Spy的完整日志輸出,便于調試。 - 生產環境:關閉SQL日志輸出,僅保留異常日志或慢SQL監控。
- 日志過濾:通過正則表達式排除無關表(如
flw_*
),減少冗余信息。 - 性能優化:利用P6Spy的慢SQL檢測功能,持續優化數據庫操作。
掌握這些配置技巧后,開發者不僅能提升調試效率,還能在復雜業務場景中保障系統的穩定性與性能。
附錄:常見問題解答
Q1: 為什么SQL日志中沒有顯示實際參數值?
A1: 確保使用P6Spy而非MyBatis Plus默認的StdOutImpl
,P6Spy會自動替換占位符?
為實際參數。
Q2: P6Spy配置后無法連接數據庫?
A2: 檢查driverlist
是否包含實際數據庫驅動(如com.mysql.cj.jdbc.Driver
),并確認URL格式為jdbc:p6spy:mysql://...
。
Q3: 如何將日志輸出到文件?
A3: 修改spy.properties
中的appender
配置:
appender=com.p6spy.engine.spy.appender.FileLogger
logfile=/path/to/p6spy.log
參考文獻:
- MyBatis Plus官方文檔(https://www.baomidou.com/introduce/)
- P6Spy GitHub倉庫(https://github.com/p6spy/p6spy)
- Spring Boot日志配置指南