在准备另一个Statement之前是不是需要关闭PreparedStatement

Posted

技术标签:

【中文标题】在准备另一个Statement之前是不是需要关闭PreparedStatement【英文标题】:Is it necessary to close PreparedStatement before preparing another Statement在准备另一个Statement之前是否需要关闭PreparedStatement 【发布时间】:2015-10-02 07:21:55 【问题描述】:

是否需要在一个 db.getConnection() 中关闭 ResultSet 和 PreparedStatement?下面的例子:

Connection conn = db.getConnection();
PreparedStatement pstmt = conn.prepareStatement(firstsql);
ResultSet r = pstmt.executeQuery();
// do something with the ResultSet
r.close();
pstmt.close();   // do I need close the r and pstmt here?
PreparedStatement pstmt = conn.prepareStatement(secondsql);
ResultSet r = pstmt.executeQuery();
// do something with the ResultSet again
r.close();
pstmt.close();
conn.close();
return null;

第5行和第6行的代码有必要吗?

【问题讨论】:

【参考方案1】:

严格来说,没有必要,因为您可以同时打开多个准备好的语句。 必要的是关闭每个打开的资源,如果它以后不会被使用。

查看您的代码,它并不能确保该语句实际上是关闭的。

为确保这一点,每个关闭操作都必须在 finally 块内完成:这样,无论操作成功与否,它都会执行。

示例代码:

PreparedStatement pstmt = null;
ResultSet r = null;
try 
    pstmt = conn.prepareStatement(firstsql);
    r = pstmt.executeQuery();
    // do something with the ResultSet
 finally 
    if (r != null) 
        try 
            r.close();
         catch (SQLException e) 
            //log error
        
    
    if (pstmt != null) 
        try 
            pstmt.close();
         catch (SQLException e) 
            //log error
        
    

//and do it again

如果您使用带有try-with-resources 语句的Java 7,则可以大大简化此代码:

try (PreparedStatement pstmt = conn.prepareStatement(firstsql);
      ResultSet r = pstmt.executeQuery();) 
    // do something with the ResultSet

【讨论】:

【参考方案2】:

没有。您可以同时打开多个语句。但你最终必须关闭它们。

您发布的代码无法编译,如果编译了,则会发生资源泄漏,但这与您标题中的问题不同。

【讨论】:

谢谢。阅读完所有 cmets 后,我明白您所说的“否”和“资源泄漏”是什么意思。

以上是关于在准备另一个Statement之前是不是需要关闭PreparedStatement的主要内容,如果未能解决你的问题,请参考以下文章

c3p0 Prepared Statement 无故关闭

在打开另一个下拉菜单之前完全关闭一个下拉菜单

什么是Statement

在executeBatch()之前如何检查Prepared Statement是不是有一些批次?

django模板if或statement

Laravel:一般错误:1615 Prepared statement需要重新准备