Zachowanie zestawów wyników i (przygotowanych) instrukcji jest wyraźnie udokumentowane w interfejsie API Java. Sugeruję przeczytanie aktualnej dokumentacji (i specyfikacji JDBC), aby uzyskać szczegóły.
Statement
API mówi:
Domyślnie jedynym ResultSet
obiekt za Statement
obiektu mogą być otwarte w tym samym czasie. Dlatego, jeśli odczyt jednego obiektu jest przepleciony z odczytem innego, każdy musi zostać wygenerowany przez różne obiekty. Wszystkie metody wykonywania w interfejsie Statement
domyślnie zamykają bieżący obiekt obiektu ResultSet
, jeśli jest otwarty.
(podkreślenie moje).
W określonym kodzie, po wywołaniu aStmt.executeQuery()
, stary ResultSet
przypisany do aRset
jest niejawnie zamknięty przez sterownik. To powiedziawszy, byłoby lepiej wyraźnie zamknąć to samodzielnie (lub użyć Java 7 try-with-resources), aby zapobiec zapomnieniu o zamknięciu ResultSet
w ostatniej iteracji przez pętlę.
Teraz do PreparedStatement
: Kiedy przygotowujesz instrukcję (na ogół implementacja może się różnić), zapytanie jest wysyłane do serwera w celu kompilacji.Podczas wykonywania parametry dla tego konkretnego wykonania są wysyłane do serwera. Wywołanie close()
na aStmt
spowodowałoby, że przygotowana instrukcja została zwolniona na serwerze, to jest wyraźnie to, czego chcesz tutaj, ponieważ chcesz ponownie użyć instrukcji z różnymi wartościami dla jej parametru.
Tak w skrócie
- Zamknięcie
ResultSet
nie jest konieczne ze względów technicznych tutaj (z wyjątkiem ostatniego ResultSet
stworzonej), ale lepiej to zrobić jawnie
- Należy zamknąć tylko
PreparedStatement
gdy skończysz z tym.
Korzystanie try-with-resources jest jednym ze sposobów, aby usunąć część zamieszania w tych kwestiach, jak kod będzie automatycznie zwalnia zasoby, gdy jest ona z nim zrobić (na końcu zakresu stosowania):
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
}
}
}
Na końcu tego fragmentu wszystkie zasoby JDBC są poprawnie zamknięte (we właściwej kolejności, nawet jeśli wystąpiły wyjątki itp.)
W rzeczywistości, dla ostatniego zestawu wyników (wszystkich innych niezamkniętych zasobów), mam metodę, która zamyka wszystko na końcu programu. Biorąc to pod uwagę, czy pozostawienie mojej logiki jest takie, jakie jest? – heisenbergman
@heisenbergman Powinieneś zamknąć zasoby, gdy już ich nie potrzebujesz. Pozostawienie ich otwartych może zwiększyć wykorzystanie pamięci w aplikacji i bazie danych. –