2012-02-29 15 views
1

我目前正在創建許多類,它們將使用連接池訪問數據庫。 所以我得到一個連接,創建一個語句並獲得結果集。 (我不能使用Java 1.7和美妙自動資源管理) 當完成我的方法,我必須有一個finally塊完成:Java 1.6 java.sql try/catch /終於瘋狂編碼

 if (rs != null) { 
      try { 
       rs.close(); 
      } catch (SQLException sqle) { 
       logger.error("Couldn't close result set", sqle); 
      } 
     } 
     if (st != null) { 
      try { 
       st.close(); 
      } catch (SQLException sqle) { 
       logger.error("Couldn't close statement", sqle); 
      } 
     } 
     if (connection != null) { 
      try { 
       connection.close(); 
      } catch (SQLException sqle) { 
       logger.error("Couldn't close connection", sqle); 
      } 
     } 

我已經看到了噩夢這將是XX班每個方法有4/5個方法。

難道是很好的做法,使一個輔助類,這將有一個特殊的接近方法爲每個對象類型,如:

public static void closeResource(Connection connection) { 
     if (connection != null) { 
      try { 
       connection.close(); 
      } catch (SQLException sqle) { 
       logger.error("Couldn't close connection", sqle); 
      } 
     } 

然後只是在做我平時finallyxx.close(connection);xx.close(statement);xx.close(rs);

還是在同樣的想法(我知道在這一點上,我會震驚一些人,因爲我自己發現有點囉嗦),有一個像public static void closeResources(Object... obj) {}方法與instanceof可怕列表?

或者根據你的經驗,到處編碼整個事情比較好?

+0

也許看看使用方面。您可以使用aspectJ編寫此功能。 – mcfinnigan 2012-02-29 16:28:17

+0

您可能感興趣的[Spring JDBC vs Plain JDBC之間的區別?](http:// stackoverflow。com/questions/9469643) – 2012-02-29 16:29:38

+0

@TomaszNurkiewicz感謝您向我介紹Spring JDBC,我不會爲此項目付出代價,但我會牢記這一點。 – 2012-02-29 16:42:44

回答

2

使用重載。

private void close(ResultSet rSet) throws SQLException { 
    if (rSet != null) { 
     rSet.close(); 
    } 
} 

private void close(Statement statement) throws SQLException { 
    if (statement != null) { 
     statement.close(); 
    } 
} 

private void close(Connection conn) throws SQLException { 
    if (conn != null) { 
     conn.close(); 
    } 
} 

用法將現在乾淨多了:

try { 
    // do db stuff 
} catch (Exception e) { 
    logger.error("log it", e); 
} finally { 
    close(rs); 
    close(cs); 
    close(conn); 
} 
+0

是的,我在考慮如果我繼續使用方法。無論如何感謝 – 2012-02-29 16:34:01

+2

在你的代碼中,你最終沒有捕捉異常。 – 2012-02-29 16:47:09

1

只是一個例子。適用於簡單的小型項目。

Object doRequest() throws SQLException { 

    PreparedStatement ps = ... // initialize statement 
    try { 
     ResultSet rs = ps.executeQuery(); 
     try { 

      // use ResultSet 
      return someResult; 

     } finally { 
      rs.close(); 
     } 
    } finally { 
     ps.close(); 
    } 

} 

雖然它不是僞裝成完整的解決方案(許多嵌套try-finally相當不可讀),有幾個優點:

  • 方法將其自身的異常處理不交易。通常只有調用者可以決定如何處理異常。
  • 如下所示,方法總是返回正確結果引發異常。沒有魔術「錯誤值」需要。
  • 資源僅在初始化時關閉。無需檢查null berode close()
0

您也可以利用這個事實,要關閉所有的課,close方法具有無參數,使反射的輔助方法是這樣的:

public static final void tryClose(Object o){ 
     if(o != null){ 
      Method[] m = o.getClass().getMethods(); 
      for (Method method : m) { 
       if("close".equals(method.getName())){ 
        if(!method.isAccessible()) method.setAccessible(true); 
        try { 
         method.invoke(o); 
        } catch (Exception e) { 
         System.err.println(e); 
        } 
        break; 
       } 
      } 
     }  
    } 

編輯:測試用的FileWriter,在我的機器上正常工作。

+0

這對我所期待的有點太多了;)。感謝分享。 – 2012-02-29 17:10:14