老王,怎麼完整SQL的顯示日誌

作者:peng
來源:http://club.oneapm.com/t/java-sql/154

在常規項目的開發中可能最容易出問題的地方就在於對數據庫的處理了,在大部分的環境下,我們對數據庫的操作都是使用流行的框架,比如 Hibernate 、 MyBatis 等。

由於各種原因,我們有時會想知道在這些框架下實際執行的 SQL 究竟是什麼。

雖然 Hibernate 可以在配置文件中打開 SHOW SQL 的功能, MyBatis 則可以在 Log4j 的配置文件中配置 SQL 語句的輸出,但這些輸出是類似這樣的 INSERT … ? ? ? 語句,並不是一個完整可以運行的 SQL ,要想知道完整的 SQL 需要手動把參數補齊,如果要調試這樣的 SQL 無疑非常痛苦。

Log4jdbc 是一個開源 SQL 日誌框架,它使用代理模式實現對常用的 JDBC Driver( Oracle , Derby , MySQL , PostgreSQL , H2 , HSQLDB , …)操作的攔截,記錄真實 SQL ,可以將佔位符與參數全部合併在一起顯示,方便直接拷貝 SQL 在 MySQL 等客戶端直接執行,加快調試速度。

本文主要介紹如何使用 Log4jdbc 這個可以直接顯示完整 SQL 的日誌框架,希望對大家能有所幫助。

# Log4jdbc 的特點


Log4jdbc 的官方主頁是 https://github.com/arthurblake/log4jdbc 4 ,它具有以下特點:

完全支持 JDBC3 和 JDBC4

配置簡單,在大多數情況下,只需要將 JDBC 驅動類改成 net.sf.log4jdbc.DriverSpy ,同時將 jdbc:log4jdbc 添加到現有的 JDBC URL 之前,最後配置日誌記錄的種類即可

將 Prepared Statements 中的綁定參數自動插入到對應的位置。在大多數情況下極大改善了可讀性及調試工作

SQL 的耗時信息能被獲取從而幫助判斷哪些語句執行得過慢,同時這些信息可以被工具識別得到一個關於慢 SQL 的報表

SQL 連接信息也可以獲取從而幫助診斷關於連接池或線程的問題

兼容任何 JDBC 驅動,需要 JDK1.4 及以上與 Slf4j1.x

開源軟件,使用 Apache 2.0 License

使用 Log4jdbc 的步驟

感興趣的朋友可以去 Log4jdbc 的項目主頁看它的使用方法,如果單純使用 Log4jdbc ,不會對 ResultSet 以表格方式呈現,在這裡我們使用擴展自 Log4jdbc 的日誌框架 Log4jdbc-log4j2 ,它增加了對 ResultSet 以表格方式呈現的處理,項目主頁是: https://code.google.com/p/log4jdbc-log4j2/ 3 。它的使用步驟如下:

1、決定使用哪個版本的 JAR 包:

如果使用 JDK1.5 , 應該使用 JDBC3 版本的 JAR 包即 log4jdbc-log4j2-jdbc3.jar

如果使用 JDK1.6 , 應該使用 JDBC4 版本的 JAR 包即 log4jdbc-log4j2-jdbc4.jar (即使實際使用的 JDBC 驅動是 JDBC3 的甚至更老)。

如果使用 JDK1.7 , 應該使用 JDBC4.1 版本的 JAR 包即 log4jdbc-log4j2-jdbc4.1.jar (即使實際使用的 JDBC 驅動是 JDBC3 的甚至更老)。

2、將 JAR 包添加進項目:

將 JAR 包添加進項目有兩種方式,第一種是直接將 Log4jdbc-log4j2 和 Slf4j 的 JAR 包添加進 CLASSPATH 中,第二種是使用 MAVEN 方式引入 JAR 包,這裡我們主要說明第二種方式。在 pom.xml 文件中,根據使用的 JDBC 驅動的版本來替換 log4jdbc-log4j2-jdbcXX (比如 log4jdbc-log4j2-jdbc4.1 , 或者 log4jdbc-log4j2-jdbc4 , 或者 log4jdbc-log4j2-jdbc3 )。該框架需要配合 Slf4j 一起使用,MAVEN 配置如下:

老王,怎麼完整SQL的顯示日誌

3、將項目的配置文件中的 JDBC 驅動類改成

net.sf.log4jdbc.sql.jdbcapi.DriverSpy 。

4、將 jdbc:log4 添加到現有的 JDBC URL 之前:

例如原來的 JDBC URL 是


jdbc:mysql://localhost:3306/MyDatabase

,則應該改成:

jdbc:log4jdbc:mysql://localhost:3306/MyDatabase

5、配置日誌記錄的種類:

Log4jdbc 用以下幾個可以配置的日誌種類:

1.jdbc.sqlonly : 僅記錄 SQL

2.jdbc.sqltiming :記錄 SQL 以及耗時信息

3.jdbc.audit :記錄除了 ResultSet 之外的所有 JDBC 調用信息,會產生大量的記錄,有利於調試跟蹤具體的 JDBC 問題

4.jdbc.resultset :會產生更多的記錄信息,因為記錄了 ResultSet 的信息

5.jdbc.connection :記錄連接打開、關閉等信息,有利於調試數據庫連接相關問題

以上日誌種類都可以設置為 DEBUG , INFO 或 ERROR 級別。當設置為 FATAL 或 OFF 時,意味關閉記錄。

以下是一個採用 Log4j 作為具體日誌系統的典型配置,將這些配置到

log4j.properties 裡面:


log4j.logger.jdbc.sqlonly=OFF
log4j.logger.jdbc.sqltiming=INFO
log4j.logger.jdbc.audit=OFF
log4j.logger.jdbc.resultset=OFF
log4j.logger.jdbc.connection=OFF

6、添加 log4jdbc.log4j2.properties 文件:

這是最後一步,在項目的 CLASSPATH 路徑下創建一個 log4jdbc.log4j2.properties 文件,告訴 Log4jdbc-log4j2 使用的是 Slf4j 來記錄和打印日誌,在該配置文件裡增加:

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator

最後,運行一下項目,看看效果。

# 效果


老王,怎麼完整SQL的顯示日誌

上圖可以看出,兩個 SELECT 語句的執行時間分別是 117 和 552 毫秒,這對於開發調試還是很有幫助的。現在很多的項目壓測時和上線後,基本都在使用 OneAPM ,它的數據庫監控 2分析功能更強大一些,不僅可以記錄 SQL 日誌,還可以定位到操作 SQL 的 Java 代碼行,直接在網頁上就可以看到效果,使用體驗還是不錯的。


分享到:


相關文章: