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

如何正确地处理同时循环中的连接、结果集和语句对象

萧宣
2023-03-14

如果我有以下代码,这是关闭Connection、ResultSet和语句对象的正确方式吗?我觉得所有对关闭()的调用都应该在最终块中。

Connection con = null;
ResultSet rs = null;
Statement stmt = null;

try{
    //Code before the while loop 
    con = DriveManager.getConnection("Stuff");

    while(someBoolean){          

        stmt = con.createStatement();
        rs = stmt.executeQuery("SQL query");

        // do stuff with query results.

        if( rs != null){
               rs.close();
        }

        if( stmt != null){
               stmt.close();
        }

} //end while

    if( con != null ){
        con.close();
    }

catch (Exception e){
    //handle exception
}

共有3个答案

邵城
2023-03-14

在Java 7中,可以使用try with resource语句:

try(Connection con = getConnection(url, username, password, "drivername");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
) {

  //statements
}catch(....){}

在Java 6中,您可以最后关闭块中的资源:

} finally {
   try { rs.close(); } catch (Exception e) {  }
   try { ps.close(); } catch (Exception e) {  }
   try { conn.close(); } catch (Exception e) {  }
}

您甚至可以使用帮助类来关闭连接。Apache Commons DbUtils有一个DbUtils类。

} finally {
    DbUtil.closeQuietly(rs);
    DbUtil.closeQuietly(ps);
    DbUtil.closeQuietly(conn);
}
郑衡
2023-03-14

您不需要在循环中创建语句:您可以重用它。此外,使用Java7尝试使用资源(教程),您不需要处理以正确顺序关闭的单调乏味等。

你可以这样做:

try (
    Connection con = DriverManager.getConnection("Stuff");
    Statement stmt = con.createStatement();
){
    while(someBoolean){          
        try (ResultSet rs = stmt.executeQuery("SQL query")) {
            // do stuff with query results.
        }
    } //end while
} catch (Exception e){
    //handle exception
}

如您所见,与自己管理它相比,它需要的检查和语句要少得多,同时它确保以正确的顺序关闭资源,即使发生异常(即使在关闭其他资源之一时发生该异常)。例如,如果发生任何异常,您的旧代码无法关闭资源。

赖运珧
2023-03-14

是的,关闭资源应该在一个finally块中,因为无论在哪里抛出异常,都应该关闭所有资源。

标准图案为:

Connection con = null;
ResultSet rs = null;
Statement stmt = null;

try {
    con = DriveManager.getConnection("Stuff");
    stmt = con.createStatement();
    rs = stmt.executeQuery("SQL query");
    // do stuff with query results
} catch (SQLException e) { // Don't catch Exception, catch what you expect
    // handle exception
} finally {
    // each close can itself explode, so wrap each in try catch
    try {
       if (rs != null)
           rs.close();
    } catch (SQLException ignore) {} // no point handling

    try {
       if (stmt != null)
           stmt.close();
    } catch (SQLException ignore) {} // no point handling

    try {
       if (con != null)
           con.close();
    } catch (SQLException ignore) {} // no point handling
}

虽然未能关闭其中一个资源可能意味着其他资源也将爆炸,但它尝试关闭每一个仍然是很好的做法,因此每个人都会在最后一个区块内尝试捕捉。

 类似资料:
  • 我在研究mysqli准备的声明,我有两个问题。 在阅读过程中,我发现预处理语句的执行顺序如下所示: 这是我的第一个问题: 在我阅读时,它还提到以下内容: 如果不将结果绑定到变量,请使用$row=$stmt- 他们使用这两种方法中的任何一种来循环结果集是否有任何优点/缺点?如果没有区别,那么为什么还要麻烦使用$stmt绑定结果呢- 这是我的另一个问题: $stmt- 希望你的回答能让我更好地理解事先

  • 问题内容: 可以说我必须在for循环内使用if语句,并且for循环在特定条件下触发,而if语句仅在for循环达到特定阶段时才触发。 例如,条件是一个计数器,该计数器在发生某些事情(例如,球从屏幕上掉下来)时进行计数。每次球越过屏幕时,都会一圈绘制一个圆圈。当第一行中的圆圈到达屏幕的末端时,圆圈开始出现在第一行下方的第二行中。但是第二行对我不起作用,我已经用if语句实现了。 if语句仅在第一行的球越

  • db架构包含表AUTHOR和BOOK,列如下: 问题是,对象在没有作者的书时用默认值填充。如何检测左联接没有右表的对象?一种方法是检查图书主键字段是否为空。还有别的办法吗?

  • 我最近和我的教授讨论了如何处理基本的jdbc连接方案。假设我们要执行两个查询,这是他提出的 我不喜欢这种方法,对此我有两个问题: 1.A)我认为,如果在我们做“其他事情”的地方,或在或那么当方法结束时,s1就不会被关闭。我说得对吗? 1.B)教授一直要求我明确关闭结果集(即使声明文档明确表明它将关闭结果集),她说孙建议这样做。有什么理由这样做吗? 现在,我认为这是同样事情的正确代码: 2. A)此

  • 问题内容: 我正在尝试在MySQL中编写一个存储过程,该存储过程将执行一个稍微简单的选择查询,然后循环遍历结果,以便决定是执行其他查询,数据转换还是完全丢弃数据。有效地,我想实现这一点: 只有,我只希望在MySQL中使用它,因此可以将其称为过程。我知道对于触发器来说,有语法,但是找不到在语法之外使用的类似内容。我已经阅读了MySQL中的一些循环机制,但到目前为止,我所能想象的就是我将实现以下内容:

  • 通常都听到别人说,计算机很牛逼,很聪明,其实计算机一点都不聪明,光是你要跟他沟通,都会气 shi 你,聪明的是在写程序的你。 写程序就是跟计算机沟通,告诉它要做什么。 竟然是这样,那么肯定缺少不了一些沟通逻辑。比如你要告诉计算机在什么情况下做什么?或者在哪个时间点做什么? 这都需要用到逻辑判断。这一章节,主要就是说这个。 目录