2011-07-15 17 views
9

¿El uso de PreparedStatements y ResultSets crea una "nueva instancia de base de datos" cada vez que se utilizan? O, en otras palabras, si utilizo un PreparedStatement y un ResultSet, ¿debo cerrarlos después de cada uso o una vez que termine?Cierre de declaraciones preparadas

Ejemplo:

while (...){ 
     p = connection.prepareStatement(...); 
     r = p.executeQuery(); 
     while (r.next()) { 
     .... 
     } 
} 
// We close at the end. Or there are any other p and r still opened...? 
p.close(); 
r.close(); 

O

while (...){ 
     p = connection.prepareStatement(...); 
     r = p.executeQuery(); 
     while (r.next()) { 
     .... 
     } 
     p.close(); 
     r.close(); 
} 

NOTA: Por supuesto que me gustaría utilizar tratar de cerrar correctamente, esto es sólo un ejemplo.

+0

Los cierra en un bloque finally, por lo que se asegura que esté cerrado incluso si hay alguna excepción de tiempo de ejecución – chedine

Respuesta

5

Debe cerrar cada uno que abra. Cuando crea una declaración preparada o un conjunto de resultados, la base de datos asigna recursos para ellos, y cerrarlos le dice a la base de datos que libere esos recursos (es probable que la base de datos reasigne estos recursos después de un período de tiempo de espera, pero al llamar cerca la base de datos sabe que puede seguir y limpiar). Su segundo ejemplo es mejor, excepto que cerraría el conjunto de resultados antes de la declaración preparada.

Así, con bloques try incluido que se vería así:

while (...){ 
     PreparedStatement p = connection.prepareStatement(...); 
     try { 
      ResultSet r = p.executeQuery(); 
      try { 
      while (r.next()) { 
       .... 
      } 
      } finally { 
      try { 
       r.close(); 
      } catch (SQLException e) { 
      // log this or something -- prevent these from masking original exception 
      } 
      } 
     } 
     finally { 
      try { 
      p.close(); 
      } catch (SQLException e) { 
      // log this or something -- prevent these from masking original exception 
      } 
     } 
} 

la captura de las excepciones a partir del cierre es feo, pero si usted tiene una excepción lanzada durante la ejecución de la declaración preparada, o durante el recorrido de los resultados establecer, desea asegurarse de que lo ve, y no una excepción lanzada al cerrar la declaración preparada o conjunto de resultados (que se debe a un error de red que no puede hacer nada de todos modos).

También tenga en cuenta que el uso de try-with-resources funcionará, excepto que si tiene un caso en que la operación de la base de datos tiene éxito pero llama a cerrar resultados en una excepción, se lanzará la excepción.

Recomiendo a las personas que utilicen la biblioteca spring-jdbc (que se encarga de cerrar todo por ti) en lugar de generar iffy o verbose jdbc a mano.

+0

¿Alguna ayuda aquí? :) http://stackoverflow.com/questions/35849664/sonar-close-this-preparedstatement –

5

La primera forma es mejor.

Sin embargo, debe saber que puede volver a utilizar declaraciones preparadas (de ahí el nombre "preparado") si el SQL que está utilizando es el mismo cada vez. Por ejemplo:

//Note: try/catch/finally blocks removed for brevity 
p = connection.prepareStatement(...); 
while (...){ 
    r = p.executeQuery(); 
    while (r.next()) { 
     .... 
    } 
    r.close(); 
} 
p.close(); 
+1

+1 para reutilizar la declaración preparada –

+0

¿Alguna ayuda aquí? :) http://stackoverflow.com/questions/35849664/sonar-close-this-preparedstatement –

1

Incluso si usted no desea utilizar la primavera, o Apache dbUtils, o similares, reconocer que hay un montón de repetitivo aquí que te gustaría enviar un factor fuera de sus rutinas de consulta para que se tiene que repetirlo lo menos posible.

Cuestiones relacionadas