2011-12-15 4 views
30

Я создаю новую версию своего приложения на демо-сервере и хотел бы найти способ сброса базы данных ежедневно. Наверное, у меня всегда может быть выполнение задания cron и создание запросов, но я ищу более чистый подход. Я пробовал использовать специальный модуль сохранения с помощью метода drop-create, но он не работает, так как система часто и часто отключается от сервера (по запросу).Периодически сбрасывать встроенную базу данных H2

Есть ли лучший подход?

ответ

55

H2 поддерживает специальное заявление SQL для drop all objects:

DROP ALL OBJECTS [DELETE FILES] 

Если вы не хотите, чтобы удалить все таблицы, вы можете захотеть использовать truncate table:

+0

Спасибо. Я работаю при выполнении этого. – javydreamercsw

+1

TRUNCATE TABLE не сбрасывает счетчики AUTO_INCREMENT до нуля :( – Nazar

+2

@Nazar, да, это то же поведение, что и другие базы данных, например PostgreSQL (с использованием 'serial'). Я думаю, что это правильное поведение, так как значения могут быть использованы в других таблицах. –

1

Команда: ВЫКЛЮЧЕНИЕ
Вы можете выполнить его с помощью RunScript.execute (jdbc_url, user, password, "classpath: shutdown.sql", "UTF8", false);
я запускать его каждый раз, когда набор тестов закончен с использованием @AfterClass

12

В этот ответ является первым результатом Google для «сброса базы данных H2», я отправляю мое решение ниже:

После каждого JUnit @tests:

  • ограничение целостности Отключить
  • Список всех таблиц в (по умолчанию) PUBLIC схемы
  • Округление все таблицы
  • Список всех последовательностей в (по умолчанию) PUBLIC схемы
  • Сброс всех последовательностей
  • снова включить ограничения.

    @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(); 
    } 
    

Другим решением было бы recreatethe базу данных в начале каждого испытания. Но это может быть слишком долго в случае большой БД.

+0

это работает очень хорошо, спасибо – aliopi

1

Thre специальный синтаксис в Spring для манипулирования базами данных в блок тестирует

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

В этом примере мы выполняем drop_all.sql скрипт (где мы Dropp все необходимые таблицы) после каждый метод испытания. В этом примере мы выполняем create.sql скрипт (где мы создаем все необходимые таблицы) и init.sql сценария (где мы инициализации перед тем каждый метод испытаний все необходимые таблицы.

Смежные вопросы