关闭PreparedStatements

时间:2011-07-15 15:25:37

标签: java database recordset

使用PreparedStatements和ResultSets是否每次使用时都会创建“新数据库实例”? 或者,换句话说,如果我使用PreparedStatement和ResultSet,我应该在每次使用后关闭它们还是在完成后关闭它们?

示例:

while (...){
        p = connection.prepareStatement(...);
        r = p.executeQuery();
        while (r.next()) {
        ....
        }
 }
 // We close at the end. Or there are any other p and r still opened...?
 p.close();
 r.close();

OR

while (...){
        p = connection.prepareStatement(...);
        r = p.executeQuery();
        while (r.next()) {
        ....
        }
        p.close();
        r.close();
 }

注意:当然我会尝试并正确关闭,这只是一个例子。

3 个答案:

答案 0 :(得分:5)

你应该关闭你打开的每一个。当您创建预准备语句或结果集时,数据库会为这些语句或结果集分配资源,关闭它们会告诉数据库释放这些资源(可能数据库最终会在超时期限后重新分配这些资源,但调用close会让数据库知道它可以继续前进并清理)。你的第二个例子更好,除了我在准备好的语句之前关闭结果集。

因此,如果包含try块,它将如下所示:

while (...){
        PreparedStatement p = connection.prepareStatement(...);
        try {
          ResultSet r = p.executeQuery();
          try {
            while (r.next()) {
              ....
            }
          } finally {
            try {
              r.close();
            } catch (SQLException e) {
            // log this or something -- prevent these from masking original exception
            }
          }
        }
        finally {
          try {
            p.close();
          } catch (SQLException e) {
            // log this or something -- prevent these from masking original exception
          }
        }
 }

从关闭中捕获异常很难看,但是如果在执行预准备语句期间抛出异常,或者在遍历结果集期间抛出异常,则需要确保看到它,而不是在抛出异常时抛出异常。关闭准备好的声明或结果集(由于某些网络故障,你无论如何都无法做任何事情)。

还要注意使用try-with-resources会有效,除非你有一个数据库操作成功但调用close导致异常的情况,那么异常将被抛出。

我建议人们使用spring-jdbc库(处理关闭所有内容),而不是手动启动iffy或verbose jdbc。

答案 1 :(得分:5)

第一种方式更好。

但是,如果您使用的SQL每次都相同,您应该知道可以重复使用预准备语句(因此名称为“准备好”)。例如:

//Note: try/catch/finally blocks removed for brevity
p = connection.prepareStatement(...);
while (...){
    r = p.executeQuery();
    while (r.next()) {
        ....
    }
    r.close();
}
p.close();

答案 2 :(得分:1)

即使您不想使用Spring,Apache DbUtils或类似产品,也要认识到这里有很多样板文件,您希望将它们从查询例程中分解出来,这样您就必须重复几次尽可能。