Ответ 1
Поведение результатов и (подготовленных) операторов явно описано в Java API. Я предлагаю вам прочитать фактическую документацию (и спецификацию JDBC), чтобы получить подробную информацию.
API Statement
говорит:
По умолчанию только один объект
ResultSet
для объектаStatement
может быть открыт одновременно. Поэтому, если чтение одного объектаResultSet
чередуется с чтением другого, каждый из них должен быть сгенерирован разными объектамиStatement
. Все методы выполнения в интерфейсеStatement
неявно закрывают текущий объектResultSet
статусом, если существует открытый.
(основное внимание).
В вашем конкретном коде, когда вы вызываете aStmt.executeQuery()
, старый ResultSet
, назначенный aRset
, неявно закрывается драйвером. Тем не менее, было бы лучше явно закрыть его самостоятельно (или использовать Java 7 try-with-resources), чтобы вы не забыли закрыть 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 правильно закрыты (в правильном порядке, даже если произошли исключения и т.д.)