Java7之后,将ResultSet放入嵌套的try-with-resources语句中是一个好的实践吗?

9
根据http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#close()文档的说明,当Statement对象关闭时,如果存在当前ResultSet对象,则也将被关闭。但是根据Must JDBC Resultsets and Statements be closed separately although the Connection is closed afterwards?的解释,明确地关闭Connection、Statement和ResultSet似乎是一个好习惯。如果我们仍然需要关闭ResultSet,则可能需要一个嵌套的try-with-resources语句,因为我们可能需要像这样设置Statement的参数:
try (Connection conn = connectionProvider.getConnection();
     PreparedStatement pstmt = conn.prepareStatement(sql) {//resources of conn and pst

     setPrepareStatementParameter(pstmt, kvs);//need to set parameters, so I have to put ResultSet into another try-with-resources statement

     try (ResultSet res = pstmt.executeQuery()) {
                ..............

     }
}

问题:

ResultSet 放入单独的 try-with-resources 语句中是否有用,因为文档说明关闭 Statement 将关闭 ResultSet

2个回答

4
您的示例覆盖了连接、语句和结果集之间互动的范围太有限。请考虑以下内容:
try (Connection conn = connectionProvider.getConnection();
     PreparedStatement pstmt = conn.prepareStatement(sql);) {

     for (int i = 0; i < kvs.length; i++) {
         setPrepareStatementParameter(pstmt, kvs[i]);

         // do other stuff

         // Place the ResultSet in another try with resources
         // to ensure the previous iteration's ResultSet
         // is closed when the next iteration begins
         try (ResultSet res = pstmt.executeQuery()) {
             ..............

         }
     }
 }

在上面的示例中,PreparedStatement 是参数化的,并在 for 循环内执行了 kvs.length 次。想象一下,如果参数化过程由于任何原因而花费了很长时间,那么关闭 PreparedStatement 对我们没有帮助,因为我们想要在 for 循环的每次迭代中重用已编译的 SQL 语句。那么将 ResultSet 嵌套到自己的 try-with-resources 块中——从而确保前一个迭代的 ResultSet 被关闭,但 PreparedStatement 仍然保持打开状态——是值得付出努力的。

0

是的,你应该关闭或使用try-resources来处理结果集。

为什么呢?

我引用了其他答案中我读到的内容,对我来说很有道理。

  • 理论上,关闭语句会关闭结果集。
  • 在实际操作中,一些有缺陷的JDBC驱动程序实现未能这样做。

请查看完整答案: https://dev59.com/I2Eh5IYBdhLWcg3wNxIn#45133734


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接