1. 概述
Spring JDBC 和 JPA 提供對原生 JDBC API 的抽象,允許開發者擺脱原生 SQL 查詢。然而,我們經常需要查看這些自動生成的 SQL 查詢以及它們執行的順序,以便進行調試。
在本快速教程中,我們將探討在 Spring Boot 中記錄這些 SQL 查詢的不同方法。
2. 記錄 JPA 查詢
2.1. 輸出到標準輸出
將查詢輸出到標準輸出的最簡單方法是向 application.properties 添加以下內容:
spring.jpa.show-sql=true為了美化或格式化顯示 SQL,我們可以添加:
spring.jpa.properties.hibernate.format_sql=true使用上述配置,日誌將打印如下:
2024-03-26T23:30:42.680-04:00 DEBUG 9477 --- [main] org.hibernate.SQL:
select
c1_0.id,
c1_0.budget,
c1_0.end_date,
c1_0.name,
c1_0.start_date
from
campaign c1_0
where
c1_0.start_date between ? and ?雖然這非常簡單,但不建議這樣做,因為它直接將所有內容輸出到標準輸出,沒有任何日誌框架的優化。
此外,它不會記錄預處理語句的參數。
2.2. 通過日誌記錄器
現在,讓我們看看如何通過在 properties 文件中配置日誌記錄器來記錄 SQL 語句:
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE第一行記錄 SQL 查詢,第二條語句記錄預處理語句的參數。
在配置中,漂亮的打印特性也將生效。
通過設置這些屬性,日誌將被髮送到配置的 appender。 Spring Boot 默認使用 logback 及其標準 out appender。
如果我們想記錄帶有綁定參數的查詢,可以在 application.properties 文件中添加一個屬性來實現它。
logging.level.org.hibernate.orm.jdbc.bind=TRACE上述屬性將 Hibernate 的日誌級別設置為 TRACE,用於 JDBC 綁定,該綁定會記錄詳細信息以及綁定參數:
org.hibernate.SQL : select c1_0.id,c1_0.budget,c1_0.end_date,c1_0.name,c1_0.start_date from campaign c1_0 where c1_0.start_date between ? and ?
org.hibernate.orm.jdbc.bind : binding parameter [1] as [DATE] - [2024-04-26]
org.hibernate.orm.jdbc.bind : binding parameter [2] as [DATE] - [2024-04-05]3. 記錄 JdbcTemplate 查詢
為了配置使用 JdbcTemplate 時執行語句的日誌記錄,我們需要兩個額外的屬性:logging.level.org.springframework.jdbc.core.JdbcTemplate=DEBUG
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE與 JPA 日誌配置類似,第一行用於記錄日誌語句,第二行用於記錄預處理語句的參數。 採用上述配置,SQL 日誌將包含綁定參數:
2024-03-26T23:45:44.505-04:00 DEBUG 18067 --- [main] o.s.jdbc.core.JdbcTemplate: Executing prepared SQL statement [SELECT id FROM CAMPAIGN WHERE name = ?]
2024-03-26T23:45:44.513-04:00 TRACE 18067 --- [main] o.s.jdbc.core.StatementCreatorUtils: Setting SQL statement parameter value: column index 1, parameter value [sdfse1], value class [java.lang.String], SQL type unknown
4. 記錄所有類型的查詢
使用攔截器是記錄所有類型 SQL 查詢的最佳方法。 通過這種方法,我們可以攔截 JDBC 調用,對其進行格式化,然後以自定義格式記錄 SQL 查詢。
datasource-proxy 庫是流行的框架之一,它攔截 SQL 查詢並進行記錄。我們需要在 pom.xml 文件中添加它的依賴項:
<dependency>
<groupId>com.github.gavlyukovskiy</groupId>
<artifactId>datasource-proxy-spring-boot-starter</artifactId>
<version>1.12.1</version>
</dependency>同時,我們需要更新該屬性以啓用對 datasource-proxy 的日誌記錄:
logging.level.net.ttddyy.dsproxy.listener=debug現在,有了這個配置,它將打印一份包含查詢和參數等詳細信息的漂亮日誌:
Name:dataSource, Connection:15, Time:1, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["select c1_0.id,c1_0.budget,c1_0.end_date,c1_0.name,c1_0.start_date from campaign c1_0 where c1_0.start_date between ? and ?"]
Params:[(2024-04-26,2024-04-05)]需要注意的是,攔截器方法會記錄來自 JPA、JPQL 和 Prepared Statements 的所有查詢。
5. 它是如何工作的?
Spring/Hibernate 類,它們生成 SQL 語句並設置參數,已經包含用於記錄這些語句的代碼。
但是,這些日誌語句的級別分別設置為 DEBUG 和 TRACE,低於 Spring Boot 的默認級別 INFO。
通過添加這些屬性,我們只是將這些日誌記錄器設置為所需的級別。
6. 結論
在本文中,我們探討了在 Spring Boot 中記錄 SQL 查詢的幾種方法。我們還研究了記錄 SQL 查詢的綁定參數。最後,我們討論了攔截器方法是記錄 SQL 查詢和綁定參數的最佳方法。
如果我們選擇配置多個附加器,還可以將 SQL 語句和其他日誌語句分開存儲到不同的日誌文件中,以保持整潔。