在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你的ResultSet
, Statement
和Connection
(按照这个顺序),就像这样:
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),这也可能有帮助。
closuresStatement
和Connection
就足够了。 没有必要显式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连接或来自池的连接的调用。