结果集和(预准备的)语句的行为在 Java API 中明确记录。我建议您阅读实际文档(和JDBC规范)以获取详细信息。
语句
API 说:
默认情况下,每个对象只能同时打开一个对象。因此,如果一个对象的读取与另一个对象的读取交错,则每个对象必须由不同的对象生成。如果存在打开的语句对象,则 Statement
接口中的所有执行方法都会隐式关闭语句的当前 ResultSet
对象。ResultSet
Statement
ResultSet
Statement
(强调我的)。
在特定代码中,当您调用 时,分配给 的旧代码由驱动程序隐式关闭。也就是说,最好自己显式关闭它(或使用Java 7 try-with-resources),以防止您忘记通过循环在最后一次迭代中关闭。aStmt.executeQuery()
ResultSet
aRset
ResultSet
现在到:当您准备语句时(通常,实现可能会有所不同),查询将发送到服务器进行编译。执行时,该特定执行的参数将发送到服务器。调用将导致在服务器上解除分配预准备语句,这显然不是您在此处想要的,因为您希望重新使用具有不同参数值的语句。PreparedStatement
close()
aStmt
所以简而言之
- 这里从技术上讲,关闭不是必需的(除了最后创建的),但最好明确地执行此操作
ResultSet
ResultSet
- 您只应在完成后关闭 。
PreparedStatement
使用 try-with-resources 是消除这些问题的部分混淆的一种方法,因为您的代码将在完成操作后自动释放资源(在使用范围结束时):
try (
ResultSet cRset = cStmt.executeQuery(cQuery);
PreparedStatement aStmt = aConn.prepareStatement(aQuery);
) {
while (cRset.next()) {
//stuff to determine value of parm1
aStmt.setString(1, parm1);
try (ResultSet aRset = aStmt.executeQuery()) {
//more stuff
}
}
}
在这段代码的末尾,所有JDBC资源都被正确关闭(以正确的顺序,即使发生异常等)