在Java中closures数据库连接

我感到有点困惑,我从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(); } 

你不需要closures连接? 如果conn.close()没有发生,真正发生了什么?

我有一个私人的networking应用程序,我维持目前没有closures任何forms,但是真正的重要的一个,连接一,还是两者?

该网站断断续续地下降,但服务器不断说这是一个数据库连接问题,我怀疑是它没有被closures,但我不知道如果任何closures。

当你完成使用你的Connection ,你需要通过调用close()方法来明确地closures它,以释放连接可能持有的任何其他数据库资源(游标,句柄等)。

实际上,Java中的安全模式是当你完成它们的时候,在finally块中closures你的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块可以稍微改进(避免null检查):

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

但是,这仍然是非常冗长的,所以你通常最终使用一个辅助类来closures对象的空安全的帮助方法和finally块变成这样的:

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

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

使用后closures数据库/资源​​对象总是更好。 最好closuresfinally块中的连接,结果集和语句对象。

在Java7之前,所有这些资源都需要使用finally块来closures。 如果您正在使用Java 7,那么可以按照以下步骤closures资源。

 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在使用后自动closures这些资源。

希望我是有帮助的。

是。 您需要closures结果集,语句和连接。 如果连接来自池,closures它实际上将其发送回池以供重用。

您通常必须在finally{}块中执行此操作,因此如果抛出exception,您仍然有机会closures它。

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

closuresStatementConnection就足够了。 没有必要显式closuresResultSet对象。

有关java.sql.ResultSet Java文档说明:

当Statement对象closures,重新执行或用于从多个结果序列中检索下一个结果时,Statement对象会自动closuresResultSet对象。


感谢BalusC的评论: “我不会依赖于这个,一些JDBC驱动程序会失败。”

是的,你需要closures连接。 否则,数据库客户端通常会保持套接字连接和其他资源打开。

实际上,如果您使用try-with-resources模块,Java会在您退出try模块时closures所有连接。

你应该用任何实现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的调用只是组成。 将其replace为可获取JDBC SQL连接或来自池的连接的调用。