Java 正确使用JDBC资源的方法

Java 正确使用JDBC资源的方法,java,jdbc,try-with-resources,Java,Jdbc,Try With Resources,即使在Java7中,我也经常看到这样的代码 Connection c = null; PreparedStatement s = null; try { c = dataSource.getConnection(); String sql = "insert into table (column1, column2) values (?, ?); s = c.prepareStatement(sql); i

即使在Java7中,我也经常看到这样的代码

    Connection c = null;
    PreparedStatement s = null;
    try {
        c = dataSource.getConnection();

        String sql = "insert into table (column1, column2) values (?, ?);
        s = c.prepareStatement(sql);
        int i = 1;
        s.setString(i++, "111");
        s.setString(i++, "222");

        s.execute();

    } catch (SQLException e) {
        log.error("failed to insert", e);
    } finally {
        DbUtils.close(s, c); // closes s and c with no questions
    }
但根据规范,当连接关闭时,所有语句和结果集都被释放


我听说JDBC驱动程序有可能不遵守JDBCAPI的规则,而旧方法更好。我的问题是听听大家对此的看法。代码看起来更好,但如果有危险呢?
在我看来,最喜欢的方式是在这里使用尝试使用资源。足够安全吗?

您应该始终释放/关闭您使用的资源,如结果集、语句、连接。这应该在最后一块中完成。粘贴到此处的代码段看起来正常(只要s和c在QuietDb中关闭)。

资源是一个对象,必须在程序完成后关闭。因此,您不必在
finally
块中手动关闭该对象

 String sql = "insert into table (column1, column2) values (?, ?);
    try(Connection  c = dataSource.getConnection();
    PreparedStatement s = c.prepareStatement(sql);) {


        int i = 1;
        s.setString(i++, "111");
        s.setString(i++, "222");

        s.execute();

    } catch (SQLException e) {
        log.error("Failed to insert transaction", e);
    } 
然而,在大多数数据库中,对于任何一个
连接
可以同时打开的
语句的数量有一个上限

如果不关闭
语句
s,则会增加出现错误的可能性,例如
ORA-01000:超过最大打开游标数


如果关闭
语句
,则不必同时关闭这两个语句。

使用
尝试使用资源
可以将代码重写为:

try (
    Connection c = dataSource.getConnection();
    PreparedStatement s = c.prepareStatement("insert into table (column1, column2) values (?, ?)");
) {
    int i = 1;
    s.setString(i++, "111");
    s.setString(i++, "222");

    s.execute();
} catch (SQLException e) {
    log.error("failed to insert", e);
}
这保证语句和连接都被关闭(即使关闭语句会引发异常!)。唯一的区别可能是关闭时的异常现在可能会被抛出,因为我不知道您的
DbUtils.close
是否会吞噬异常


总的来说,try with resources提供了更清晰的代码,并且更能保证资源以正确的顺序正确关闭,而不需要太多的锅炉板。

什么样的问题是“可以吗?”。?您自己也说过:“尝试使用资源”是一种更好的处理方式。我听说JDBC驱动程序有可能不遵守JDBCAPI的规则,而旧的方式更好。我的问题是听听大家对此的看法。代码看起来更好,但如果有危险怎么办?好吧,这就是你应该在问题中提出的。@FedorovMikhail“旧方法更好”?我认为这表明了对try-with-resources如何工作的理解不足,因为从技术上讲try-with-resources与您的代码是一样的,除非出现错误时使用较少的锅炉板和实际的异常反馈。这是假设实现表现良好,但并非总是如此。完成后最好显式关闭资源。