当前位置: 首页 > 知识库问答 >
问题:

为什么调用语句。close()不是立即释放由语句对象创建的ResultSet对象吗?

庾君博
2023-03-14

来自JDBC规范

关闭语句对象将关闭该语句对象生成的任何ResultSet实例并使其无效。在垃圾收集再次运行之前,ResultSet对象持有的资源可能不会被释放,因此当不再需要ResultSet对象时,显式关闭它们是一种很好的做法。

>

  • 调用ResultSet.close()是否立即释放ResultSet对象?

    调用Statement.close()是否立即释放语句对象?

    调用语句。close()释放由语句对象创建的ResultSet对象,那么为什么它不立即释放ResultSet对象呢?

  • 共有3个答案

    严瀚昂
    2023-03-14

    关于关闭JDBC对象的注意事项。

    在Java SE 7中,可以使用try with资源来管理JDBC对象。连接、语句、结果集、行集扩展了java.lang.AutoCloseable。try with resources语句确保在语句末尾关闭每个资源(无论块中的代码如何完成)。

    以下是一些示例Java和JDBC代码-请注意,语句和结果集是在try-with-Resources块中创建的。

    public void printAllBooks()
            throws SQLException {
        String sql = "SELECT * FROM book_table";
        try(Statement stmnt = conn.createStatement(); // conn is the Connection object
            ResultSet rs = stmnt.executeQuery(sql)) {
            while (rs.next()) {
                System.out.println("Id: " + rs.getString("book_id") +
                        " Author: " + rs.getString("author") +
                        " Title: " + rs.getString("title"));
            }
        }
    }
    

    注:

    • 可以在try with resources语句中声明一个或多个资源
    • try with resources语句可以有可选的catch和/或finally块。任何catch或finally块都是在声明的资源关闭后运行的
    • 当直接跟随try with resources的代码块终止时,通常或由于异常而终止,语句和结果集的close()方法将自动按其创建的相反顺序调用

    侯博易
    2023-03-14

    根据结果集SE 8#close(),它似乎立即发布

    语句SE 8相同

    当生成结果集的语句对象关闭时,结果集也会自动关闭。

    当生成结果集的语句对象关闭、重新执行或用于从多个结果序列中检索下一个结果时,结果集对象将自动关闭。

    陈奇希
    2023-03-14

    来自语句的Javadoc。close()(强调mine):

    立即释放这个语句对象的数据库和JDBC资源,而不是等到它自动关闭时才释放。通常,最好在使用完资源后立即释放资源,以避免占用数据库资源。

    对已关闭的对象调用方法close无效。

    注意:当关闭一个语句对象时,其当前的结果集对象(如果存在)也将关闭。

    在这里,Javadoc声明关闭一个语句立即释放其资源,并关闭其当前的结果集。

    ResultSet.close()的Javadoc(强调我的):

    立即释放这个结果集对象的数据库和JDBC资源,而不是等到它自动关闭时才释放。

    关闭ResultSet对象不会关闭由ResultSet创建的BlobClobNClob对象。BlobClobNClob对象至少在创建它们的事务期间保持有效,除非调用它们的自由方法。

    关闭ResultSet时,通过调用getMetaData方法创建的任何ResultSetMetaData实例仍然可以访问。

    注意:ResultSet对象在关闭、重新执行或用于从多个结果序列中检索下一个结果。

    在已经关闭的ResultSet对象上调用该方法是无操作的。

    此Javadoc声明关闭ResultSet也会立即释放其资源。并且,如上所述,调用Statement.close()也会关闭ResultSet

    该注释还指出,在任何给定时间,每个语句只能打开一个结果集。如果您提出另一个请求(或如前所述,满足任何其他条件),则先前的结果集将自动关闭。

    注意:所有Javadoc报价和链接都适用于Java10。

     类似资料:
    • 问题内容: 以下程序本身并不重要。它只使用类Counter内部的静态字段,通过使用for循环来计算创建的对象数,如下所示。 唯一的问题是,注释的for循环的含义与上述for循环的含义相同(同一事实也适用于while循环)根本不起作用,从而导致指示“ 不是语句 ” 的编译时错误。意味着在这种特殊情况下,即使for循环仅包含一个语句,一对括号也是必须的!为什么? 问题答案: 要了解为什么会发生这种情况

    • 问题内容: 在JavaScript中,声明在全局对象上创建属性: ES6引入了具有作用域范围的声明的词法作用域。 但是,这些声明是否在全局对象上创建属性? 问题答案: 语句是否在全局对象上创建属性? 根据规范,否: 全局环境记录在逻辑上是单个记录,但是它被指定为封装对象环境记录和声明性环境记录的复合记录。该对象环境记录作为其基本对象相关的全局对象境界。该全局对象是全局环境记录的GetThisBin

    • 在JavaScript中,声明在全局对象上创建属性: ES6使用具有块作用域的声明引入词法作用域。 但是,这些声明是否在全局对象上创建属性?

    • 我还没有看到这个问题,这让我很惊讶。 以下内容不会编译: 然而,将此更改为强制转换对象并将其引用存储在条件语句之外的新对象中,可以解决此问题: 我的问题是,为什么Java中不允许这种行为?(特别是Java 5) 编辑:啊哈!谢谢大家。该死的现代IDE给出了模糊的错误消息。我已经开始打折了,这一次对我没有任何好处。(Netbeans警告我缺少括号和分号…)

    • 问题内容: 例如: 相对于: 一个比另一个更有效吗? 问题答案: 返回之前分配给临时变量使您有机会从newPerson()中进行错误检查和更正。返回新的调用要求newPerson()方法的调用者捕获错误并从错误中恢复。

    • 问题内容: 我最近了解到,可以在语句中创建新的对象,如下所示: 这是要避免的事情还是应该接受?根据良好实践,何时才可以合理使用此功能? 问题答案: 不要回避它 ,因为有第 10.2.7.2节 所提醒的,因为它有完全有效的用例,所以这里有SELECT NEW 。 EJB 3.0 JPA规范 的SELECT子句 中的 JPQL构造函数表达式 : SELECT列表中可以使用构造函数来返回一个或多个Jav