正确关闭各种JDBC对象的顺序

时间:2013-04-15 02:54:03

标签: java oracle jdbc cursor

我有以下代码示例:

try {
    conn = this.jdbcTemplate.getDataSource().getConnection();
    stm = conn.prepareCall("{? =" + query + "}");
    stm.registerOutParameter(1, OracleTypes.CURSOR);
    if (params != null) {
        for (int i = 0; i < params.length; i++)
            stm.setString(i + 2, params[i]);
    }
    //getting result set from cursor
    stm.execute();
    res = (ResultSet) stm.getObject(1);
    return DatabaseLayerUtils.getResultSetData(res);
} finally {
    //closing cursor
    if (res != null) res.close();
    if (stm != null) stm.close();
    if (conn != null) conn.close();
}

finally部分中的元素顺序是否重要?

是以下代码:

 if (res != null) res.close();
 if (stm != null) stm.close();

等于:

 if (stm != null) stm.close();
 if (res != null) res.close();
是不是?

在我的同事正在进行的项目中,有很多结构如:

 if (stm != null) stm.close();
 if (res != null) res.close();

我需要了解这是否是正确的语法,或者我是否需要修复如下所示:

 if (res != null) res.close();
 if (stm != null) stm.close();

感谢。

2 个答案:

答案 0 :(得分:4)

如果关闭Connection,则无需显式关闭ResultSet和Statement。据我所知,所有JDBC驱动程序现在都能正确处理。

如果要在一行中显式关闭它们,则需要按照创建的相反顺序关闭它们:ResultSet,Statement,Connection。

此外,您需要将每个关闭包装到try / catch中,因为就我记忆而言,它们会抛出异常。

更好的是,如果您使用close(ResultSet rs)close(Statement stmnt)close(Connection cnn)方法进行了一些完整的课程。

<强> UPD

现在又有一个新的(已经两年了)的方法来关闭JDBC(不仅限于JDBC)。

Java7引入了一项名为“try-with-resources”http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

的新功能

教程(上面的链接)非常明显,所以我认为现在注意到这个功能已经足够了。

对于JDBC资源的目的,您可以在try-with-resources中注册Statement并跳过关闭ResultSet(在try .. {之后照常声明),因为这将自动发生,如我在第一部分中所述。

答案 1 :(得分:1)

  

最后一节中的元素顺序是否重要?

是。如果先关闭连接,则另一个关闭是多余的,可以省略。如果你想要按照相反的获取顺序关闭所有内容。

为了获得最大的清晰度和灵活性,我这样做:

Connection conn = ...;
try
{
  PreparedStatement ps  = ...;
  try
  {
    // ps.setXXXXX() ...
    ResultSet rs = ps.executeQuery();
    try
    {
      // ...
    }
    finally
    {
      rs.close();
    }
  }
  finally
  {
    ps.close();
  }
}
finally
{
  conn.close();
}

然后我可以在晚上睡觉,知道没有逃脱;-)也不需要空测试。