2016-01-20 36 views
0

以下代码无法编译,因为PreparedStatement.close()和ResultSet.close()都会引发java.sql.SQLException。那么,我是否将try/catch块添加到finally子句中?或者将关闭语句移入try子句中?或者只是不打扰关闭?关闭java PreparedStatement和ResultSets

PreparedStatement ps = null; 
ResultSet rs = null; 
try { 
    ps = conn.createStatement(myQueryString); 
    rs = ps.executeQuery(); 
    // process the results... 
} catch (java.sql.SQLException e) { 
    log.error("an error!", e); 
    throw new MyAppException("I'm sorry. Your query did not work."); 
} finally { 
    ps.close(); 
    rs.close(); 
} 

回答

2

。利用Java 7中引入的新功能,try-with-resources Statement

例如...

try (PreparedStatement ps = conn.createStatement(myQueryString)) { 
    // bind parameters 
    try (ResultSet rs = rs = ps.executeQuery()) {} 
     // process the results... 
    } 
} catch (java.sql.SQLException e) { 
    log.error("an error!", e); 
    throw new MyAppException("I'm sorry. Your query did not work."); 
} 
1

使用try-与资源块,(在Java 7中引入的),这会自动为你关闭资源。

这里是您发布的等效代码,用一个try-与资源块改写:

try(PreparedStatement ps = conn.createStatement(myQueryString)) 
{ 
    ResultSet rs = ps.executeQuery(); 
    // process the results... 
} catch(SQLException e) { 
    log.error("an error!", e); 
    throw new MyAppException("I'm sorry. Your query did not work."); 
} 

注:
这是没有必要呼吁这里的ResultSet close(),因为根据Statement.close() doc:

当一个Statement对象关闭时,它的当前ResultSet对象(如果存在的话)也被关闭。

1

有几种方法可以做到这一点。

首先也是最简单的,如果您正在使用Java 7,则执行try-with-resource,如其他答案中所述。

第二种方法,您可以将一个try/catch添加到finally块。建议先关闭ResultSet,然后按Statement,最后Connection

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

第三个方法是使用外部库如Commons DbUtils它负责所有关闭你。

finally { 
    org.apache.commons.dbutils.DbUtils.closeQuietly(rs); 
    org.apache.commons.dbutils.DbUtils.closeQuietly(ps); 
}