2009-12-21 21 views
2

這是java數據訪問代碼的好風格,還是最終嘗試太多?java數據訪問:這是java數據訪問代碼的好風格,還是試試最後呢?

public List<Item> getItems() throws ItemException { 
    ArrayList<Item> items = new ArrayList<Item>(); 
    try { 
     Connection con = ds.getConnection(); 
     try { 
      PreparedStatement pStmt = con.prepareStatement("SELECT ...."); 
      try { 
       ResultSet rs = pStmt.executeQuery(); 
       try { 
        while (rs.next()) { 
         Item item = new Item(); 
         item.setItemNo(rs.getString("item_id")); 
         // ... 
         items.add(item); 
        } 
       } finally { 
        rs.close(); 
       } 
      } finally { 
       pStmt.close(); 
      } 
     } finally { 
      con.close(); 
     } 
    } catch (SQLException e) { 
     throw new ItemException(e); 
    } 
    return items; 
} 
+0

'ArrayList的項目=新的ArrayList ();'應該是' List items = new ArrayList ();' – 2013-05-02 21:56:39

+0

我建議你去休眠。它有很多功能。 Aarons的代碼看起來不錯,但是如果你每次都使用JDBC的話。您最終會創建大量與數據庫的連接,這可能會對應用程序的性能產生影響。 – akellakarthik 2009-12-21 08:53:24

回答

3

它比較我的代碼:

Connection con = null; 
PreparedStatement pStmt = null; 
ResultSet rs = null; 
try 
{ 
    con = ds.getConnection(); 
    pStmt = con.prepareStatement("SELECT ...."); 
    rs = pStmt.executeQuery(); 
    while (rs.next()) { 
     Item item = new Item(); 

     item.setItemNo(rs.getString("item_id")); 
     ... 

     items.add(item); 
    } 
} 
finally { 
    rs = DBUtil.close (rs); 
    pStmt = DBUtil.close (rs); 
    con = DBUtil.close (rs); 
} 

這裏是close()樣子:

public static ResultSet close (ResultSet rs) { 
    try { 
     if (rs != null) 
      rs.close(); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
     // Or use your favorite logging framework. 
     // DO NOT THROW THIS EXCEPTION OR IT WILL 
     // HIDE EXCEPTIONS IN THE CALLING METHOD!! 
    } 
    return null; // Make sure no one uses this anymore 
} 

[編輯]您需要複製此代碼爲其他類型。

我也感動到所有這些所謂的DBOp一個輔助類,所以我只需要重寫processRow(ResultSet row)做實際的處理,我可以忽略所有的樣板代碼。在Java 5中的DBOp構造上寫着:

public DBOp (Logger log, DataSource ds, String sql, Object... param) 

我傳遞的記錄,所以我可以顯示哪些情況下實際上是調查數據。

+0

我想你忘了在第二次調用時忘記將參數更改爲close()。 – 2009-12-21 09:22:47

+0

是的,你需要爲每個JDBC類型創建一個這樣的代碼副本:(我希望Sun會讓他們實現'Closeable'。 – 2009-12-21 10:30:06

+0

如果getConnection()從一個池中獲得一個Connection,那麼它不應該被關閉。我認爲關閉語句也會自動關閉ResultSet – 2009-12-21 11:35:12

3

根據API DOC,StatementsResultSets隱含地與所述連接關閉,所以是 - 的那些2嘗試/最後塊是不必要的(和非常難看)。爲了減少內存使用量,在保留單個Connection以進行大量查詢時,明確關閉語句可能會很有用。

+0

除了最簡單的代碼之外,你應該手動關閉它們,否則它們會停下來。 – 2009-12-21 08:43:57

+1

不可以。如果您確定連接已關閉,則所有可能出現的對象都是對象本身,手動關閉它們也不會阻止該對象。 – 2009-12-21 10:58:14

2

...並且您不應該關閉該方法中的連接。它看起來像,你將Connection對象存儲在那個對象中。所以你應該讓它到ds關閉它。否則,有可能DS返回與getConnection()方法已關閉連接的風險,我認爲,這是一個不必要的和意外的行爲;)

+0

......除非'ds'對象碰巧是'DataSource',當然你必須在完成之後關閉連接。 .sun.com/javase/6/docs/api/javax/sql/DataSource.html – Dirk 2009-12-21 09:26:56

+0

@Dirk,良好的捕獲和(太)簡短的變量名稱暗示你是對的。我想到了傳統的DriverManager磨片重新獲得通過靜態方法的連接。 – 2009-12-21 10:09:11