0

我有以下代码示例:

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

谢谢。

4

2 回答 2

4

如果关闭 Connection,则不需要显式关闭 ResultSet 和 Statement。据我所知,所有 JDBC 驱动程序现在都可以正确处理这个问题。

如果要连续显式关闭它们,则需要以与创建相反的顺序关闭它们:ResultSet、Statement、Connection。

此外,您需要将每个 close 包装到 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 .. {),因为正如我在第一部分中描述的那样,这将自动发生。

于 2013-04-15T03:10:17.417 回答
1

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

是的。如果您先关闭连接,则其他关闭是多余的,可以省略。如果您想关闭所有内容,您应该按照获取的相反顺序进行操作。

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

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

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

于 2013-04-15T04:07:07.443 回答