2011-12-15 16 views
30

私はデモ用のサーバーに自分のアプリケーションの新しいバージョンを設定しており、毎日データベースをリセットする方法を探しています。私は常にクローンジョブを実行してクエリを作成することができますが、私はよりクリーンなアプローチを探しています。私はdrop-createアプローチで特別な永続ユニットを使用しようとしましたが、システムが頻繁に(オンデマンドで)サーバに接続したり切断したりしても機能しません。定期的に組み込みH2データベースをリセットする

良いアプローチがありますか?

答えて

55

H2がdrop all objectsに特別なSQL文をサポートしています。

DROP ALL OBJECTS [DELETE FILES] 

あなたはすべてのテーブルをドロップしたくない場合は、truncate tableを使用することがあります:

+0

感謝を実行します – javydreamercsw

+1

TRUNCATE TABLEはAUTO_INCREMENTカウンタをゼロにリセットしません。( – Nazar

+2

@Nazar、はい、これはPostgreSQL( 'serial'を使用)などの他のデータベースと同じ動作です。値が他のテーブルで使用される可能性があります。 –

1

コマンド:SHUTDOWN
RunScript.execute(jdbc_url、user、password、 "classpath:shutdown.sql"、 "UTF8"、false)を使用して実行できます。
私は、この応答は、「H2データベースをリセットする」ための最初のGoogleの結果であるとしてテストのスイートを@AfterClass

12

を使用して終了するたびに、私は以下の私のソリューション投稿し、それを実行します:各後

を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することであろう。しかし、それは大きなDBの場合には長すぎるかもしれません。

+0

これはとてもうまく動作します、ありがとう – aliopi

1

THREは、ユニット内のデータベース操作のため春に特別な構文であるが、この例で

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

をテスト我々は(我々は必要なすべてのテーブルをdropp)drop_all.sqlスクリプト後のすべての試験方法を実行します。 この例では、我々は、私が働いています。(私たちはすべての必要なテーブルを作成する)てcreate.sqlスクリプトと init.sql我々は前各テストメソッドを、必要なすべてのテーブルを初期化するスクリプト(。

関連する問題