如何有效地記錄 Java SQL 日誌?

在常規項目的開發中可能最容易出問題的地方就在於對數據庫的處理了,在大部分的環境下,咱們對數據庫的操做都是使用流行的框架,好比 Hibernate 、 MyBatis 等。因爲各類緣由,咱們有時會想知道在這些框架下實際執行的 SQL 到底是什麼。 html

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

Log4jdbc 是一個開源 SQL 日誌框架,它使用代理模式實現對經常使用的 JDBC Driver( Oracle , Derby , MySQL , PostgreSQL , H2 , HSQLDB , …)操做的攔截,記錄真實 SQL ,能夠將佔位符與參數所有合併在一塊兒顯示,方便直接拷貝 SQL 在 MySQL 等客戶端直接執行,加快調試速度。本文主要介紹如何使用 Log4jdbc 這個能夠直接顯示完整 SQL 的日誌框架,但願對你們能有所幫助。mysql

Log4jdbc 的特色:

Log4jdbc 的官方主頁是 https://github.com/arthurblake/log4jdbc ,它具備如下特色:git

  • 徹底支持 JDBC3 和 JDBC4github

  • 配置簡單,在大多數狀況下,只須要將 JDBC 驅動類改爲 net.sf.log4jdbc.DriverSpy ,同時將 jdbc:log4jdbc 添加到現有的 JDBC URL 以前,最後配置日誌記錄的種類便可sql

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

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

  • 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/ 。它的使用步驟以下:

一、決定使用哪一個版本的 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 的甚至更老)。

二、將 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 配置以下:

<dependency>
    <groupId>org.bgee.log4jdbc-log4j2</groupId>
    <artifactId>log4jdbc-log4j2-jdbcXX</artifactId>
    <version>1.16</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.2</version>
</dependency>

三、將項目的配置文件中的 JDBC 驅動類改爲 net.sf.log4jdbc.sql.jdbcapi.DriverSpy 。

四、將 jdbc:log4 添加到現有的 JDBC URL 以前:

例如原來的 JDBC URL 是

jdbc:mysql://localhost:3306/MyDatabase

,則應該改爲:

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

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

Log4jdbc 用如下幾個能夠配置的日誌種類:

  • jdbc.sqlonly : 僅記錄 SQL

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

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

  • jdbc.resultset :會產生更多的記錄信息,由於記錄了 ResultSet 的信息

  • 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

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

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

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

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

效果:

如何有效地記錄 Java SQL 日誌?

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

相關文章
相關標籤/搜索