while statement from example java jdbc resultset

java - statement - ¿La reutilización de un estado de cuenta y un conjunto de resultados libera recursos de su uso anterior? ¿O tengo que cerrarlas explícitamente antes de volver a usarlas?



statement java (3)

API PreparedStatement: una sentencia de SQL se precompila y se almacena en un objeto PreparedStatement. Este objeto se puede usar para ejecutar esta declaración de manera eficiente varias veces.

Pero no puede reutilizar un objeto ResultSet. Cuando llama a executeQuery en un objeto PreparedStatement la segunda vez que se crea un ResultSet nuevo, si no cierra el ResultSet anterior, corre el riesgo de obtener una fuga de recursos.

Código de muestra:

aStmt = aConn.prepareStatement(aQuery); aRset = aStmt.executeQuery(cQuery); while (cRset.next()) { //stuff to determine value of parm1 aStmt.setString(1, parm1); aRset = aStmt.executeQuery(); //more stuff }

¿Tengo que cerrar aStmt y aRset después de cada bucle dentro de la sentencia while? ¿O reutilizarlos en los bucles siguientes liberará la memoria / recursos utilizados de los bucles anteriores?


El comportamiento de los conjuntos de resultados y las declaraciones (preparadas) se documenta explícitamente en la API de Java. Le sugiero que lea la documentación real (y la especificación JDBC) para obtener los detalles.

La API de la Statement dice:

De forma predeterminada, solo se puede abrir un objeto ResultSet por objeto Statement al mismo tiempo. Por lo tanto, si la lectura de un objeto ResultSet se intercala con la lectura de otro, cada uno debe haber sido generado por diferentes objetos Statement . Todos los métodos de ejecución en la interfaz de Statement cierran implícitamente el objeto ResultSet actual de una declaración si existe uno abierto.

(énfasis mío).

En su código específico, cuando llama aStmt.executeQuery() , el antiguo ResultSet asignado a aRset está implícitamente cerrado por el controlador. Dicho esto, sería mejor cerrarlo explícitamente (o usar Java 7 try-with-resources), para evitar que se olvide de cerrar el ResultSet en la última iteración a través del bucle.

Ahora a la declaración PreparedStatement : cuando prepara una declaración (en general, la implementación puede variar), la consulta se envía al servidor para su compilación. En la ejecución, los parámetros para esa ejecución específica se envían al servidor. Si se llama a close() en aStmt , la declaración preparada se desasignará en el servidor, que claramente NO es lo que quiere aquí, ya que desea reutilizar la declaración con diferentes valores para su parámetro.

Así que en breve

  1. Cerrar ResultSet no es técnicamente necesario aquí (a excepción del último ResultSet creado), pero es mejor hacerlo explícitamente
  2. Solo debe cerrar la PreparedStatement cuando haya terminado con ella.

El uso de try-with-resources es una forma de eliminar parte de la confusión sobre estos problemas, ya que su código liberará automáticamente los recursos cuando termine (al final del alcance de uso):

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 } } }

Al final de este fragmento de código, todos los recursos JDBC están cerrados correctamente (en el orden correcto, incluso si se produjeron excepciones, etc.)


No, no puede cerrar ResultSet y Statement dentro del bucle while.

Tienes que cerrarlas después del bucle.

Además, si desea reutilizar PreparedStatement , puede que no lo cierre hasta que esté listo con su procesamiento.

La mejor regla es cerrar dichos recursos en el mismo bloque que se crearon. En su caso, lo mejor que puede hacer es cerrar los recursos en un bloque finally después de capturar la SQLException .

P.ej

try { aStmt = aConn.prepareStatement(aQuery); cRset = cStmt.executeQuery(cQuery); while (cRset.next()) { //stuff to determine value of parm1 aStmt.setString(1, parm1); try { aRset = aStmt.executeQuery(); } finally { aRset.close(); } //more stuff } } catch (SQLException ex) { // Do error handling } finally { // Close Resultset }

En Java 7 puedes usar try con recursos.