关闭 Java 中的数据库连接

我有点糊涂了,我正在阅读 返回文章页面 Java 数据库连接 Java数据库连接:的下面内容:

Connection conn = DriverManager.getConnection(
"jdbc:somejdbcvendor:other data needed by some jdbc vendor",
"myLogin",
"myPassword" );


Statement stmt = conn.createStatement();
try {
stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
// It's important to close the statement when you are done with it
stmt.close();
}

您不需要关闭 conn连接吗? 如果没有发生 conn.close () ,到底会发生什么?

我有一个私人的网络应用程序,我维护,目前没有关闭任何形式,但是重要的一个真的是 stmt的,conn的,或两者兼而有之?

网站一直断断续续地关闭,但服务器一直说这是数据库连接问题。我怀疑它没有被关闭,但我不知道关闭哪一个,如果有的话。

350398 次浏览

是的,您需要关闭 Connection。否则,数据库客户端通常将保持套接字连接和其他资源处于打开状态。

是的。您需要关闭结果集、语句和连接。如果连接来自池,则关闭它实际上会将其发送回池进行重用。

通常必须在 finally{}块中执行此操作,以便在抛出异常时仍有机会关闭此异常。

许多框架将为您处理这个资源分配/释放问题。例如,Spring 的 JdbcTemplateApache DbUtils有方法来关闭结果集/语句/连接(无论是否为 null)(并在关闭时捕获异常) ,这也可能有所帮助。

使用完 Connection后,需要通过调用它的 close()方法显式关闭它,以释放连接可能持有的任何其他数据库资源(游标、句柄等)。

实际上,Java 中的安全模式是在使用完 finally块之后,按照这个顺序关闭 ResultSetStatementConnection。就像这样:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;


try {
// Do stuff
...


} catch (SQLException ex) {
// Exception handling stuff
...
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) { /* Ignored */}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) { /* Ignored */}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) { /* Ignored */}
}
}

finally块可以稍作改进(以避免空检查) :

} finally {
try { rs.close(); } catch (Exception e) { /* Ignored */ }
try { ps.close(); } catch (Exception e) { /* Ignored */ }
try { conn.close(); } catch (Exception e) { /* Ignored */ }
}

但是,这仍然非常冗长,因此您通常最终使用一个 helper 类来关闭 null-safe helper 方法中的对象,并且 finally块变成如下所示:

} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}

实际上,Apache Commons DbUtils有一个 DbUtils类,它正是这样做的,所以没有必要编写自己的。

只关闭 StatementConnection就足够了,不需要显式关闭 ResultSet对象。

Java 文档介绍了 java.sql.ResultSet:

在关闭、重新执行或用于从多个结果序列检索下一个结果时,由 Statement 对象生成 ResultSet 对象,并由此对象自动关闭 ResultSet 对象。


谢谢

最好在使用后关闭数据库/资源对象。 最好关闭 finally块中的连接、结果集和语句对象。

在 Java7之前,所有这些资源都需要使用 finally块关闭。如果您正在使用 Java7,那么为了关闭资源,您可以执行以下操作。

try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {


// Statements
}
catch(....){}

现在,constmtrs对象成为 try 块的一部分,Java 在使用后会自动关闭这些资源。

实际上,最好使用 试用资源块,并且在退出 try 块时 Java 将为您关闭所有连接。

您应该对实现 AutoClose 的任何对象执行此操作。

try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
String sqlToExecute = "SELECT * FROM persons";
try (ResultSet resultSet = statement.execute(sqlToExecute)) {
if (resultSet.next()) {
System.out.println(resultSet.getString("name");
}
}
} catch (SQLException e) {
System.out.println("Failed to select persons.");
}

对 getDatabaseConnection 的调用刚刚完成。将其替换为一个调用,该调用为您提供一个 JDBC SQL 连接或一个来自池的连接。

更好的做法是使用“使用资源尝试”块

try (Connection connection = DriverManager.getConnection(connectionStr, username, password)) {
try (PreparedStatement statement = connection.prepareStatement(query)) {
statement.setFetchSize(100);
try (ResultSet resultSet = statement.executeQuery()) {
List<String> results = new ArrayList<>();
while (resultSet.next()) {
String value = resultSet.getString(1);
results.add(value);
System.out.println(value);
}
return results;
}
}
}