结果集和(准备好的)语句的行为在 Java API 中明确记录。我建议您阅读实际文档(和 JDBC 规范)以获取详细信息。
Statement
API 说:
默认情况下,ResultSet
每个Statement
对象只能同时打开一个对象。因此,如果一个ResultSet
对象的读取与另一个对象的读取交错,则每个对象都必须由不同的Statement
对象生成。如果存在打开的对象,则接口中的所有执行方法Statement
都会隐式关闭语句的当前对象。ResultSet
(强调我的)。
在您的特定代码中,当您调用 时,分配给aStmt.executeQuery()
的旧版本被驱动程序隐式关闭。也就是说,最好自己显式关闭它(或使用 Java 7 try-with-resources),以防止您忘记在循环的最后一次迭代中关闭它。ResultSet
aRset
ResultSet
现在来看PreparedStatement
:当您准备一条语句时(通常,实现可能会有所不同),查询将被发送到服务器进行编译。在执行时,该特定执行的参数被发送到服务器。调用close()
onaStmt
会导致准备好的语句在服务器上被释放,这显然不是您想要的,因为您想重新使用具有不同参数值的语句。
所以简而言之
- 在这里关闭
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 资源都正确关闭(以正确的顺序,即使发生异常等)