Java8 Try-with-resource/JDBC/Play 框架:这是正确的吗?
Posted
技术标签:
【中文标题】Java8 Try-with-resource/JDBC/Play 框架:这是正确的吗?【英文标题】:Java8 Try-with-resource/JDBC/Play Framework: Is this correct? 【发布时间】:2015-03-05 13:50:44 【问题描述】:我已经使用 try-with-resources 重写了 Play2/JDBC 查询,但我不确定这是否正确。 第一个 try 块处理 Connection 和 PrepareStatement。第二次尝试处理 ResultSet。
理论上连接、语句和结果集在任何情况下都会正确关闭?是对的吗?还是我错过了一些需要处理的事情?
public static List<Item> findBySimpleSQL(String where, java.lang.Object... params)
List<Item> collection = new ArrayList<Item>();
try (Connection connection = play.db.DB.getConnection();
PreparedStatement pstmt = connection.prepareStatement("SELECT * FROM items WHERE "+where);)
int pos = 1;
for (java.lang.Object o : params)
if (o instanceof Integer) pstmt.setInt(pos, (int) o);
if (o instanceof Long) pstmt.setLong(pos, (long) o);
if (o instanceof String) pstmt.setString(pos, (String) o);
pos++;
try (ResultSet rs = pstmt.executeQuery())
while (rs.next()) collection.add(parse(rs));
catch (Exception e)
Logger.error("Error message: "+e);
return collection;
-- 向 catch 块添加日志记录。
【问题讨论】:
一件事肯定是错的:永远不要让catch
块为空。
...尤其是如果它只捕获异常
【参考方案1】:
来自 Oracle 的The try-with-resources Statement:
"资源是程序运行后必须关闭的对象 完成它。 try-with-resources 语句确保每个 资源在语句结束时关闭。任何物体 实现 java.lang.AutoCloseable,其中包括所有对象 实现java.io.Closeable,可以作为资源使用。”
在您的情况下,Connection
、PreparedStatement
和 ResultSet
都实现了AutoCloseable
接口,所以答案是:
是的,它们将被正确关闭(不确定任何情况,编码和绝对不能很好地相处)。
您可能需要阅读上述链接并确保正确捕获可能的异常。
【讨论】:
我查看了链接“try-with-resources”。有一个显示 JDBC 用法的示例。现在我想知道为什么他们不将 ResultSet 放在 try-with-resources 块中。有人说你必须关闭 ResultSet 但后来我发现了这个:docs.oracle.com/javase/7/docs/api/java/sql/…。所以看起来 ResultSet 周围的 try 块是不必要的。有什么意见吗? 好吧,再一次,这取决于。想象一下,您想在使用完 ResultSet 后重用预编译的 PreparedStatement。在这种情况下,应将 ResultSet 放入它自己的 try-with-resource 中。或者,PreparedStatement 可能被参数化并用于 for 循环...或...或。 连接、语句和结果集之间的交互并不像人们想象的那样线性。还应该考虑 JDBC 驱动程序的实现以及 conn、stmt 和 rs 被垃圾回收这一事实(至少它们是......)。 您需要进一步说明吗?或者我们可以关闭它?以上是关于Java8 Try-with-resource/JDBC/Play 框架:这是正确的吗?的主要内容,如果未能解决你的问题,请参考以下文章
Java8新特性不了解Optional类,简历上别说你懂Java8!!