简体   繁体   English

使用JDBC资源的正确方法

[英]The correct way to use JDBC resources

Quite often I see code like that even in Java 7 即使在Java 7中,我也经常看到类似的代码

    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
    }

But according to specification when the connection is closed all statements and result sets are freed. 但是根据规范,当关闭连接时,将释放所有语句和结果集。

I've heard there's a possibility to JDBC driver not to play by the rules of JDBC API, and the old way is better. 我听说JDBC驱动程序有可能不遵循JDBC API的规则,并且旧方法更好。 My question was to hear opinions about that. 我的问题是听取对此的意见。 The code looks better but what if it's dangerous? 代码看起来更好,但是如果很危险怎么办? The most preferred way seems to me is to use try-with-resources here. 在我看来,最优选的方法是在此处使用try-with-resources Is it safe enough? 它足够安全吗?

A resource is an object that must be closed after the program is finished with it.So You don't have to close the Object manually in the finally block 资源是必须在程序完成后关闭的对象。因此,您不必在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);
    } 

You should always free/close the resources you use like ResultSet, Statement, Connection. 您应该始终释放/关闭您使用的资源,例如ResultSet,Statement,Connection。 That should be done in finally block. 那应该在finally块中完成。 The snippet you pasted here looks OK (as far as s and c are closed in QuietDb). 您在此处粘贴的代码段看起来还可以(只要在QuietDb中关闭了s和c)。

While closing a Connection will close all Statement s associated with it , there's an upper limit in most databases on how many Statement s you can have open concurrently for any one Connection . 虽然关闭Connection将关闭与之关联的所有Statement ,但是在大多数数据库中,对于一个Connection可以同时打开多少Statement ,存在一个上限。

If you don't close Statement s, you increase the likelyhood of errors like ORA-01000: maximum open cursors exceeded . 如果不关闭Statement ,则会增加出现ORA-01000: maximum open cursors exceeded类的错误的可能性ORA-01000: maximum open cursors exceeded

If you close Statements , they also close their ResultSet s , so you don't have to close both. 如果关闭Statements它们也将关闭其ResultSet ,因此您不必同时关闭两者。

Using try-with-resources your code can be rewritten to: 使用try-with-resources可以将您的代码重写为:

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);
}

This guarantees that both the statement and the connection get closed (even when closing the statement throws an Exception!). 这样可以保证语句和连接都被关闭(即使关闭该语句也会引发Exception!)。 The only difference might be that an exception on close might now get thrown as I don't know if your DbUtils.close swallows exceptions. 唯一的区别可能是关闭时可能会抛出异常,因为我不知道您的DbUtils.close吞下了异常。

In general try-with-resources provides cleaner code, and more assurance that resource get closed correctly, in the right order, without too much boiler plate. 通常,try-with-resources提供了更简洁的代码,并且可以更好地确保资源以正确的顺序正确关闭,而无需花费太多时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM