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

Java 关闭各种JDBC对象的正确顺序,java,oracle,jdbc,cursor,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.lengt

我有以下代码示例:

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();
}
等于:

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

谢谢。

如果关闭连接,则无需显式关闭ResultSet和语句。据我所知,所有JDBC驱动程序现在都能正确地处理这个问题

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

此外,您还需要将每次关闭都打包到try/catch中,因为据我记忆所及,它们会抛出一个异常

更好的方法是,如果您有一些带有
close(ResultSet rs)
close(Statement stmnt)
close(Connection cnn)
方法的utlity类

UPD

现在还有一种新的(已经两年了,呵呵)方法来关闭JDBC(不限于JDBC)的东西

Java7引入了名为“尝试资源”的新特性

教程(上面的链接)是非常自解释的,所以我认为现在注意到这个特性就足够了


出于JDBC资源的目的,您可以在try with resources中注册语句,并跳过关闭结果集(在
try..{
之后像往常一样声明它)因为这将自动发生,正如我在第一部分中所描述的。

如果关闭连接,则无需显式关闭ResultSet和语句。据我所知,现在所有JDBC驱动程序都能正确处理这一问题

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

此外,您还需要将每次关闭都打包到try/catch中,因为据我记忆所及,它们会抛出一个异常

更好的方法是,如果您有一些带有
close(ResultSet rs)
close(Statement stmnt)
close(Connection cnn)
方法的utlity类

UPD

现在还有一种新的(已经两年了,呵呵)方法来关闭JDBC(不限于JDBC)的东西

Java7引入了名为“尝试资源”的新特性

教程(上面的链接)是非常自解释的,所以我认为现在注意到这个特性就足够了

出于JDBC参考资料的目的,您可以在try with resources中注册语句,并跳过关闭ResultSet(在
try..{
之后像往常一样声明它),因为这将自动发生,正如我在第一部分中所述

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

是的。如果您先关闭连接,则其他关闭是多余的,可以忽略。如果您要关闭所有连接,则应按与采集相反的顺序进行

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

Connection conn = ...;
try
{
  PreparedStatement ps  = ...;
  try
  {
    // ps.setXXXXX() ...
    ResultSet rs = ps.executeQuery();
    try
    {
      // ...
    }
    finally
    {
      rs.close();
    }
  }
  finally
  {
    ps.close();
  }
}
finally
{
  conn.close();
}
然后我可以在晚上睡觉,知道没有逃避;-)也不需要空测试

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

是的。如果您先关闭连接,则其他关闭是多余的,可以忽略。如果您要关闭所有连接,则应按与采集相反的顺序进行

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

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

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

出于好奇:你为什么不使用/显示资源试用?出于好奇:你为什么不使用/显示资源试用?