2014-12-01 462 views
3
  • 從池中獲取一個Connection閉幕資源(這可能會拋出異常)
  • 出連接的創建Statement(也可能會拋出異常)
  • 使用執行SQL查詢聲明並將其存儲在一個ResultSet(可以奉送)
  • 做的東西與查詢結果
  • 關閉ResultSet(例外!)
  • 關閉Statement(例外!)
  • 關閉Connection(例外!)

看看這段代碼:可能會拋出異常

Connection conn = null; 
    Statement st = null; 
    ResultSet set = null; 
    try { 
     conn = Database.getConnection(); 
     st  = conn.createStatement(); 
     set  = st.executeQuery("SELECT * FROM THING"); 

     // <-- Do stuff 
    } catch (Exception e) { 

    } finally { 
     // Close set if possible 
     if (set != null) { 
      try { 
       set.close(); 
      } catch (Exception e) { 

      } 
     } 

     // Close statement if possible 
     if (st != null) { 
      try { 
       st.close(); 
      } catch (Exception e) { 

      } 
     } 

     // Close connection if possible 
     if (conn != null) { 
      try { 
       conn.close(); 
      } catch (Exception e) { 

      } 
     } 
    } 

finally塊是我收我的東西。正如你所看到的,它非常混亂。我的問題是:這是清理這些資源的正確方法嗎?

+0

Guava的Closer可以模擬Java 6中的資源嘗試http://wil.boayue.com/blog/2013/09/13/java-7-automatic-resource-管理/ - 無數'closeQuietly(Closable)'方法可能有助於編寫短代碼段(儘管只是半正確的,因爲關閉資源時的異常可能意味着寫操作失敗,因此不應被忽略)。 – zapl 2014-12-01 21:12:31

回答

5

你的代碼是趕上了可關閉的資源,之前的Java 1.7例外的正確方法,但你應該抓住SQLException代替的Exception

用Java 1.7開始,你可以使用the "try-with-resources" statement,它允許你聲明,將有close()自動調用時try塊完成,節省了樣板finally代碼資源。

try (Connection conn = Database.getConnection(); Statement st = conn.createStatement(); 
    ResultSet set = st.executeQuery("SELECT * FROM THING")) { 
    // Your "try" code as before 
} 
catch (SQLException e) { 
    // Handle as before 
} 
// No "finally" to clean up resources needed! 
+0

他應該真的使用資源嘗試嗎?因爲在除close之外的所有工作都可以使用的情況下,try-with-resources會拋出on-close異常,而發佈的代碼不會。 – 2014-12-01 21:02:41

+0

@NathanHughes這裏忽略異常是沒有問題的,因爲它只是一個讀取操作,反正大多數情況下都不會拋出。我想這就是爲什麼try-with-resource沒有內建的方式來忽略關閉錯誤,儘管一旦它可以讀取整個數據,對應用程序邏輯來說毫無意義。 – zapl 2014-12-01 21:22:50

0

是的,但你可以使它看起來通過編寫代碼(最好是在一個工具類),更好的是可重複使用的

public static void close(Statement st) { 
    if (st != null) { 
     try { 
      st.close(); 
     } catch (SQLException e) { 
      // log exception 
     } 
    } 
} 

,並在finally塊使用此方法。爲ConnectionResultSet添加類似方法