简体   繁体   English

Try-with-resources - 它会自动关闭连接吗? Java

[英]Try-with-resources - Does it automatically close the connection? Java

I've been working on a SQL utility and I am trying to set the parameters inside a prepared statement in multiple functions.我一直在研究 SQL 实用程序,我正在尝试在多个函数的准备好的语句中设置参数。

To lessen the code, I have a function that returns a prepared statement where all the params are set.为了减少代码,我有一个 function 返回一个准备好的语句,其中设置了所有参数。

My question is:我的问题是:
Does the connection reference in the configureStatement() get closed using the try with resources in the query() ? configureStatement()中的连接引用是否使用 try with resources 中的query()关闭? If not how can the code be refactored to close the PreparedStatement and the Connection every time?如果不是,如何重构代码以每次都关闭PreparedStatementConnection

    public void query(String queryString, List<String> queryParams, Consumer<ResultSet> sqlConsumer)
    {
        try (PreparedStatement preparedStatement = this.configureStatement(queryString, queryParams))
        {
            sqlConsumer.accept(preparedStatement.executeQuery());
        } catch(SQLException exception)
        {
            exception.printStackTrace();
        }
    }
    
    private PreparedStatement configureStatement(String query, List<String> queryParams) throws SQLException
    {
        PreparedStatement preparedStatement = this.getConnection().prepareStatement(query);
        for (int i = 0; i < queryParams.size(); ++i)
            preparedStatement.setString(i, queryParams.get(i));

        return preparedStatement;
    }

No, the try with resources does not close the Connection that is used inside the PreparedStatement .不,对资源的尝试不会关闭在PreparedStatement中使用的Connection Only the PreparedStatement and its ResultSet are closed.只有PreparedStatement及其ResultSet被关闭。

When a Statement object is closed, its current ResultSet object, if one exists, is also closed. 当 Statement object 关闭时,其当前 ResultSet object(如果存在)也将关闭。

It is possible to reuse a connection to execute many PreparedStatements .可以重用一个connection来执行多个PreparedStatements Each of which is closed after usage.每个都在使用后关闭。 When the connection is no longer needed it can be closed as well.当不再需要connection时,也可以将其关闭。

You could perhaps check it like this:你也许可以这样检查:

public void query(String queryString, List<String> queryParams, Consumer<ResultSet> sqlConsumer)
{
    Connection connection;
    try (PreparedStatement preparedStatement = this.configureStatement(queryString, queryParams))
    {
        connection=preparedStatement.getConnection();
        sqlConsumer.accept(preparedStatement.executeQuery());
    } catch(SQLException exception)
    {
        exception.printStackTrace();
    }
    if(connection!=null){
        System.out.println("Is Connection closed:"+connection.isClosed());
    }
}

private PreparedStatement configureStatement(String query, List<String> queryParams) throws SQLException
{
    PreparedStatement preparedStatement = this.getConnection().prepareStatement(query);
    for (int i = 0; i < queryParams.size(); ++i)
        preparedStatement.setString(i, queryParams.get(i));

    return preparedStatement;
}

A refactoring that closes connections by using the try-with-resources with multiple statements:通过将 try-with-resources 与多个语句一起使用来关闭连接的重构:

public void query(String queryString, List<String> queryParams, Consumer<ResultSet> sqlConsumer)
    {

        try ( Connection connection=this.getConnection(); 
              PreparedStatement preparedStatement = this.configureStatement(connection, queryString, queryParams);)
        {
            sqlConsumer.accept(preparedStatement.executeQuery());
        } catch(SQLException exception)
        {
            exception.printStackTrace();
        }
        if(connection!=null){
           connection.close();
        }
    }

private PreparedStatement configureStatement( Connection connection,String query, List<String> queryParams) throws SQLException
    {
        PreparedStatement preparedStatement = connection.prepareStatement(query);
        for (int i = 0; i < queryParams.size(); ++i)
            preparedStatement.setString(i, queryParams.get(i));

        return preparedStatement;
    }

Q: What makes you think returning an object from one of your own methods won't allow the object to be "closed" in a Java try with resources?问:是什么让您认为从您自己的方法之一返回 object 将不允许 object 在 Java 资源尝试中“关闭”?

From the Java documentation:来自 Java 文档:

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.任何实现 java.lang.AutoCloseable 的 object,包括实现 java.io.Closeable 的所有对象,都可以用作资源。

The key issue: the object returned from your method must implement java.lang.AutoCloseable .关键问题:从您的方法返回的 object 必须实现java.lang.AutoCloseable In your case, it does:在您的情况下,它会:

https://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html https://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html

Interface PreparedStatement接口准备语句

  • All Superinterfaces:所有超级接口:

    AutoCloseable, Statement, Wrapper AutoCloseable、声明、包装器

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

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