在Java7之后将ResultSet放入嵌套的try-with-resources语句中是一个好习惯吗?

时间:2015-02-13 06:55:24

标签: java jdbc try-catch try-with-resources

根据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 StatementResultSet似乎是一种很好的做法。

如果我们仍然需要关闭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语句中,因为doc指出关闭Statement将关闭ResultSet

2 个答案:

答案 0 :(得分:4)

您的示例涵盖了Connections,Statements和ResultSet之间的一系列交互范围。请考虑以下事项:

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保持打开 - 这是值得的。

答案 1 :(得分:0)

是的,您应该关闭或放置尝试资源作为结果集。

为什么?

我引用我从其他答案中读到的内容,这些内容对我来说很有意义。

  • 理论上,关闭语句会关闭结果集。
  • 实际上,某些错误的JDBC驱动程序实现未能做到这一点。

在此处查看完整答案: https://stackoverflow.com/a/45133734/401529