2011-12-15 21 views
30

Estoy configurando una nueva versión de mi aplicación en un servidor de demostración y me encantaría encontrar una manera de restablecer la base de datos diariamente. Supongo que siempre puedo tener una tarea cron ejecutando drop y creando consultas, pero estoy buscando un enfoque más limpio. Intenté usar una unidad de persistencia especial con el método de crear y soltar, pero no funciona, ya que el sistema se conecta y desconecta del servidor con frecuencia (a pedido).Restablecer la base de datos H2 incrustada periódicamente

¿Hay un mejor enfoque?

Respuesta

55

H2 es compatible con una declaración especial SQL para drop all objects:

DROP ALL OBJECTS [DELETE FILES] 

Si no desea colocar todas las tablas, es posible que desee utilizar truncate table:

+0

Gracias. Estoy trabajando al implementar esto. – javydreamercsw

+1

TRUNCATE TABLE no restablece los contadores AUTO_INCREMENT a cero :( – Nazar

+2

@Nazar, sí, este es el mismo comportamiento que otras bases de datos, por ejemplo PostgreSQL (usando 'serial'). Creo que es el comportamiento correcto, ya que los valores se pueden usar en otras tablas. –

1

El comando: SHUTDOWN
Puede ejecutarlo usando RunScript.execute (jdbc_url, usuario, contraseña, "classpath: shutdown.sql", "UTF8", falso);
Yo ejecuto cada vez que el conjunto de pruebas se termina usando @AfterClass

12

Como esta respuesta es el primer resultado en Google de "restablecer la base de datos H2", he puesto mi solución a continuación:

Después de cada @tests JUnit:

  • integridad Desactivar restricción
  • Lista todas las tablas de la (por defecto) de esquema PÚBLICA
  • Truncar todas las mesas
  • Lista de todas las secuencias en el (por defecto) esquema PÚBLICA
  • Restablecer todas las secuencias
  • volver a habilitar las restricciones.

    @After 
    public void tearDown() { 
        try { 
         clearDatabase(); 
        } catch (Exception e) { 
         Fail.fail(e.getMessage()); 
        } 
    } 
    
    public void clearDatabase() throws SQLException { 
        Connection c = datasource.getConnection(); 
        Statement s = c.createStatement(); 
    
        // Disable FK 
        s.execute("SET REFERENTIAL_INTEGRITY FALSE"); 
    
        // Find all tables and truncate them 
        Set<String> tables = new HashSet<String>(); 
        ResultSet rs = s.executeQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='PUBLIC'"); 
        while (rs.next()) { 
         tables.add(rs.getString(1)); 
        } 
        rs.close(); 
        for (String table : tables) { 
         s.executeUpdate("TRUNCATE TABLE " + table); 
        } 
    
        // Idem for sequences 
        Set<String> sequences = new HashSet<String>(); 
        rs = s.executeQuery("SELECT SEQUENCE_NAME FROM INFORMATION_SCHEMA.SEQUENCES WHERE SEQUENCE_SCHEMA='PUBLIC'"); 
        while (rs.next()) { 
         sequences.add(rs.getString(1)); 
        } 
        rs.close(); 
        for (String seq : sequences) { 
         s.executeUpdate("ALTER SEQUENCE " + seq + " RESTART WITH 1"); 
        } 
    
        // Enable FK 
        s.execute("SET REFERENTIAL_INTEGRITY TRUE"); 
        s.close(); 
    } 
    

La otra solución sería recreatethe base de datos en el comienzo de cada uno de las pruebas. Pero eso podría ser demasiado largo en el caso de grandes DB.

+0

esto funciona muy bien, gracias – aliopi

1

Thre es una sintaxis especial en la primavera para la manipulación de base de datos dentro de la unidad a prueba

@Sql(scripts = "classpath:drop_all.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) 
@Sql(scripts = {"classpath:create.sql", "classpath:init.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) 
public class UnitTest {} 

En este ejemplo ejecutamos drop_all.sql guión (en el que todas las tablas requeridas DROPP) después de cada método de ensayo. En este ejemplo Ejecutamos create.sql guión (donde creamos todas las tablas requeridas) y init.sql guión (en el que todas las tablas requeridas init antes de cada método de prueba.

Cuestiones relacionadas