虽然Connection之后关闭,但必须单独关闭JDBC结果集和语句吗?

据说在使用后关闭所有JDBC资源是一个好习惯。但是,如果我有以下代码,是否有必要关闭Resultset和Statement?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = // Retrieve connection
    stmt = conn.prepareStatement(// Some SQL);
    rs = stmt.executeQuery();
} catch(Exception e) {
    // Error Handling
} finally {
    try { if (rs != null) rs.close(); } catch (Exception e) {};
    try { if (stmt != null) stmt.close(); } catch (Exception e) {};
    try { if (conn != null) conn.close(); } catch (Exception e) {};
}
问题是连接的关闭是否完成了工作,或者是否使用了一些资源。     
已邀请:
你所做的是完美和非常好的练习。 我说它的良好实践的原因...例如,如果由于某种原因你使用“原始”类型的数据库池并且你调用
connection.close()
,连接将被返回到池中并且
ResultSet
/
Statement
将永远不会被关闭然后你会遇到很多不同的新问题! 所以你不能总是依靠
connection.close()
来清理。 我希望这有帮助 :)     
借助try-with-resources语句,Java 1.7让我们的生活更加轻松。
try (Connection connection = dataSource.getConnection();
    Statement statement = connection.createStatement()) {
    try (ResultSet resultSet = statement.executeQuery("some query")) {
        // Do stuff with the result set.
    }
    try (ResultSet resultSet = statement.executeQuery("some query")) {
        // Do more stuff with the second result set.
    }
}
这种语法非常简洁和优雅。即使无法创建
statement
connection
也会被关闭。     
来自javadocs:   当一个
Statement
物体关闭时,它   当前
ResultSet
对象,如果一个   存在,也是关闭的。 然而,当你关闭底层
Connection
时,j3ѭ和
ResultSet
是否关闭时,javadocs并不十分清楚。他们只是声明关闭一个连接:   发布此
Connection
对象   数据库和JDBC资源   马上而不是等待   它们会被自动释放。 在我看来,当你完成它们时,总是明确地关闭
ResultSets
Statements
Connections
,因为
close
的实现可能因数据库驱动程序而异。 您可以使用Apache的DBUtils中的
closeQuietly
等方法为自己节省大量的样板代码。     
我现在正在使用Oracle和Java。在这里我的观点: 你应该明确地关闭
ResultSet
Statement
,因为Oracle在关闭连接之前保持游标保持打开存在问题。如果不关闭
ResultSet
(光标),则会抛出超出最大打开游标的错误。 我想您可能会遇到与您使用的其他数据库相同的问题。 完成后,这是教程Close ResultSet:   完成后关闭ResultSet      完成后立即关闭
ResultSet
对象   甚至与
ResultSet
对象一起工作   虽然
Statement
对象关闭了   
ResultSet
隐含的对象   关闭,明确关闭
ResultSet
  给垃圾收集器机会   尽早回忆记忆   因为
ResultSet
对象可能占用   大量内存取决于查询。      
ResultSet.close();
    
如果你想要更紧凑的代码,我建议使用Apache Commons DbUtils。在这种情况下:
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = // Retrieve connection
    stmt = conn.prepareStatement(// Some SQL);
    rs = stmt.executeQuery();
} catch(Exception e) {
    // Error Handling
} finally {
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(stmt);
    DbUtils.closeQuietly(conn);
}
    
用于关闭与JDBC相关的资源的正确且安全的方法(取自如何正确关闭JDBC资源 - 每次):
Connection connection = dataSource.getConnection();
try {
    Statement statement = connection.createStatement();

    try {
        ResultSet resultSet = statement.executeQuery("some query");

        try {
            // Do stuff with the result set.
        } finally {
            resultSet.close();
        }
    } finally {
        statement.close();
    }
} finally {
    connection.close();
}
    
使用Java 6表单我认为最好在关闭之前检查它是否关闭(例如,如果某个连接池在其他线程中逐出连接) - 例如某些网络问题 - 语句和结果集状态可以关闭。 (它经常发生,但我在Oracle和DBCP中遇到了这个问题)。我的模式(在较旧的Java语法中)是:
    try {
        ...   
        return resp;
    } finally {
        if (rs != null && !rs.isClosed()) {
            try {
                rs.close();
            } catch (Exception e2) { 
                log.warn("Cannot close resultset: " + e2.getMessage());
           }
        }
        if (stmt != null && !stmt.isClosed()) {
            try {
               stmt.close();
            } catch (Exception e2) {
                log.warn("Cannot close statement " + e2.getMessage()); 
            }
        }
        if (con != null && !conn.isClosed()) {
            try {
                con.close();
            } catch (Exception e2) {
                log.warn("Cannot close connection: " + e2.getMessage());
            }
    }
理论上它不是100%完美,因为在检查关闭状态和关闭本身之间,状态的变化有一点空间。在最坏的情况下,你会得到一个警告。 - 但它比长期查询中状态更改的可能性要小。我们在生产中使用这种模式带有“avarage”负载(150同时用户),我们没有遇到任何问题 - 所以永远不要看到那个警告信息。     
不,你不需要关闭任何东西,但连接。根据JDBC规范,关闭任何更高的对象将自动关闭较低的对象。关闭
Connection
将关闭连接创建的任何
Statement
s。关闭任何
Statement
将关闭由该created3ѭ创建的所有
ResultSet
。如果
Connection
是否可以使用无关紧要。即使是poolable连接也必须在返回游泳池之前进行清洁。 当然,你可能在
Connection
上有很长的嵌套循环来创建大量的语句,然后关闭它们是合适的。我几乎从未关闭
ResultSet
但是,当关闭
Statement
Connection
时它似乎会过度关闭它们。     

要回复问题请先登录注册