我有点困惑,我正在阅读http://en.wikipedia.org/wiki/Java_Database_Connectivity
中的以下内容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.close(),会发生什么?
我有一个私人网络应用程序,我正在维护,目前不会关闭任何一种形式,但重要的是真正的stmt one,conn one或者两者兼而有之?
该网站间歇性地停止运行,但服务器一直说这是一个数据库连接问题,我怀疑它没有被关闭,但我不知道哪个关闭。
答案 0 :(得分:177)
完成使用Connection
后,需要通过调用close()
方法显式关闭它,以释放连接可能的任何其他数据库资源(游标,句柄等)坚持。
实际上,Java中的安全模式是在完成后ResultSet
块中关闭Statement
,Connection
和finally
(按此顺序)他们,像那样:
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 */ }
}
但是,这仍然是非常冗长,所以你通常最终使用一个帮助器类来关闭null安全帮助器方法中的对象,finally
块变成这样:
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}
实际上,Apache Commons DbUtils有一个DbUtils
类正是这样做的,所以不需要自己编写。
答案 1 :(得分:55)
使用后关闭数据库/资源对象总是更好。
最好关闭finally
块中的连接,结果集和语句对象。
在Java7之前,需要使用finally
块关闭所有这些资源。
如果您使用的是Java 7,则可以按照以下步骤关闭资源。
try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {
//statements
}catch(....){}
现在,con,stmt和rs对象成为try块的一部分,java在使用后会自动关闭这些资源。
希望我能提供帮助。
答案 2 :(得分:13)
仅关闭Statement
和Connection
即可。无需显式关闭ResultSet
对象。
Java文档说明了java.sql.ResultSet
:
当Statement对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,Statement对象会自动关闭它生成它的Statement对象。
感谢BalusC的评论:“我不会依赖它。有些JDBC驱动程序失败了。”
答案 3 :(得分:10)
是。您需要关闭结果集,语句和连接。如果连接来自池,则关闭它实际上会将其发送回池以供重用。
您通常必须在finally{}
块中执行此操作,这样如果抛出异常,您仍然有机会关闭它。
许多框架将为您处理此资源分配/解除分配问题。例如春天的JdbcTemplate。 Apache DbUtils有关闭结果集/语句/连接的方法,无论是否为null(并在关闭时捕获异常),这也可能有所帮助。
答案 4 :(得分:7)
是的,您需要关闭Connection。否则,数据库客户端通常会保持套接字连接和其他资源处于打开状态。
答案 5 :(得分:4)
实际上,最好是使用try-with-resources块,Java会在你退出try块时关闭所有连接。
您应该对任何实现AutoClosable的对象执行此操作。
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连接或池中连接的调用。