JDBC優化策略總結
相比Hibernate、iBatis、DBUtils等,理論上JDBC的性能都超過它們。JDBC提供更底層更精細的數據訪問策略,這是Hibernate等框架所不具有的。
在一些高性能的數據操做中,越高級的框架越不適合使用。這裏是我在開發中對JDBC使用過程當中一些優化經驗總結。
一、選擇純Java的JDBC驅動。
二、使用鏈接池--使用一個「池」來管理JDBC鏈接,並精心調試池配置的參數,目前可用的數據庫鏈接池不少不少。
如何配置合適的參數呢,須要的是測試,而不是感受。
三、重用Connection--最大限度使用每一個數據庫鏈接,獲得了就不要輕易「丟棄」。
有時候在一個過程當中,會屢次操做數據庫,而僅僅須要一個鏈接就夠了,沒必用一次就獲取一個鏈接,用完後關閉或者入池。這樣會增長「池」管理的成本,千萬別覺得你用了「池」就能夠隨便申請和歸還鏈接,都是有代價的。若是是一個龐大循環塊中操做數據庫,更應該注意此問題!
除此以外,還應該對鏈接進行密集使用,儘量晚的打開,並可能早的關閉。好比,你一個業務中有N多的操做,數據庫操做穿插在其中,而其餘的業務處理操做時間很長,那麼使用一個鏈接處理這些操做是有問題的。這會致使長期佔用鏈接,給數據庫帶來壓力。
四、重用Statement/PreparedStatement--對於一些預約義SQL,設置爲靜態常量,並儘量重用預約義SQL產生的PreparedStatement對象。對於屢次使用一種模式的SQL,使用預約義SQL能夠獲取更好的性能。對於Statement對象,能夠反覆的重用,每次均可以接收不一樣的SQL語句,而對於PreparedStatement則不能夠,由於預約義SQL在定義PreparedStatement對象時候已經肯定了,可是若是sql語句不變,則能夠調用clearParameters()來達到從用目的,若是sql語句發生變化,也能夠從用變量名。
五、使用批處理SQL。
六、優化結果集ResultSet--查詢時候,返回的結果集有不一樣的類型,優先選擇只讀結果集、不可滾動的屬性。
這裏是很容易出現問題的地方:
java.sql.ResultSet
static
int CLOSE_CURSORS_AT_COMMIT
該常量指示調用 Connection.commit 方法時應該關閉 ResultSet 對象。
static
int CONCUR_READ_ONLY
該常量指示不能夠更新的 ResultSet 對象的併發模式。
static
int CONCUR_UPDATABLE
該常量指示能夠更新的 ResultSet 對象的併發模式。
static
int FETCH_FORWARD
該常量指示將按正向(即從第一個到最後一個)處理結果集中的行。
static
int FETCH_REVERSE
該常量指示將按反向(即從最後一個到第一個)處理結果集中的行處理。
static
int FETCH_UNKNOWN
該常量指示結果集中的行的處理順序未知。
static
int HOLD_CURSORS_OVER_COMMIT
該常量指示調用 Connection.commit 方法時不該關閉 ResultSet 對象。
static
int TYPE_FORWARD_ONLY
該常量指示指針只能向前移動的 ResultSet 對象的類型。
static
int TYPE_SCROLL_INSENSITIVE
該常量指示可滾動但一般不受其餘的更改影響的 ResultSet 對象的類型。
static
int TYPE_SCROLL_SENSITIVE
該常量指示可滾動而且一般受其餘的更改影響的 ResultSet 對象的類型。
說明下:
結果集分兩種類型:只讀和可更改,只讀的話,更省內存,查詢的結果集不能更改。若是結果集在查詢後,更改了值又要保存,則使用可更改結果集。
結果集的遊標也有兩種類型:若是不必讓遊標自由滾動,則選擇單方向移動的遊標類型。
對因而否併發操做:若是不須要考慮線程安全,則選擇忽略併發的結果集類型,不然選擇併發安全的類型。
另外,還要控制結果的大小,幾乎全部的數據庫都有查詢記錄條數控制的策略,能夠海量數據進行分批處理,一次一批,這樣不至於把系統搞死。
七、事物優化--若是數據庫不支持事物,就不要寫回滾代碼,若是不考慮事物,就不要作事務的控制。
八、安全優化--管理好你的Connection對象,在異常時候能「入池」或者關閉。所以應該將Connection釋放的代碼寫在異常處理的finally塊中。
九、異常處理優化--不要輕易吞噬SQLException,對於DAO、Service層次的數據訪問,通常在DAO中跑出異常,在Service中處理異常。但DAO中也能夠處理異常,並作轉義拋出,不要隨便拋出RuntimeExeption,由於這是JVM拋出的,不須要你能夠去拋出,由於RuntimeException每每會致使系統掛起。
十、代碼高層優化--在以上的基礎上,優化封裝你的數據訪問方式,儘量讓代碼簡潔好維護,若是你還以爲性能不行,那就該從整個系統角度考慮優化了,好比加上緩存服務器,集羣、負載均衡、優化數據庫服務器等等,以獲取更好的系能。