Spring Bootで初期データを読み込むためのクイックガイド

Spring Bootで初期データをロードするためのクイックガイド

1. 概要

Spring Bootを使用すると、データベースの変更を簡単に管理できます。 デフォルトの構成のままにすると、パッケージ内のエンティティが検索され、それぞれのテーブルが自動的に作成されます。

ただし、データベースの変更をよりきめ細かく制御する必要がある場合もあります。 そのとき、Springでdata.sqlファイルとschema.sqlファイルを使用できます。

2. data.sqlファイル

ここで、JPAを使用していると仮定し、プロジェクトで単純なCountryエンティティを定義します。

@Entity
public class Country {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Integer id;

    @Column(nullable = false)
    private String name;

    //...
}

アプリケーションを実行すると、Spring Boot will create an empty table for us, but won’t populate it with anything.

これを行う簡単な方法は、data.sql:という名前のファイルを作成することです。

INSERT INTO country (name) VALUES ('India');
INSERT INTO country (name) VALUES ('Brazil');
INSERT INTO country (name) VALUES ('USA');
INSERT INTO country (name) VALUES ('Italy');

クラスパス上でこのファイルを使用してプロジェクトを実行すると、Springはそれを選択し、データベースへの入力に使用します。

3. schema.sqlファイル

デフォルトのスキーマ作成メカニズムに依存したくない場合があります。 このような場合、カスタムschema.sqlファイルを作成できます。

CREATE TABLE country (
    id   INTEGER      NOT NULL AUTO_INCREMENT,
    name VARCHAR(128) NOT NULL,
    PRIMARY KEY (id)
);

Springはこのファイルを選択し、スキーマの作成に使用します。

競合を避けるために、自動スキーマ作成をオフにすることを忘れないでください。

spring.jpa.hibernate.ddl-auto=none

4. Hibernateを使用したデータベース作成の制御

SpringはJPA固有のproperty which Hibernate uses for DDL generation:*spring.jpa.hibernate.ddl-auto*.を提供します

標準のHibernateプロパティ値は次のとおりです:createupdatecreate-dropvalidate、およびnone

  • create – Hibernateは最初に既存のテーブルを削除し、次に新しいテーブルを作成します

  • update –マッピング(注釈またはXML)に基づいて作成されたオブジェクトモデルが既存のスキーマと比較され、Hibernateが差分に従ってスキーマを更新します。 アプリケーションで不要になった場合でも、既存のテーブルまたは列は削除されません。

  • create-dropcreateと同様ですが、すべての操作が完了した後、Hibernateがデータベースを削除する点が追加されています。 通常、単体テストに使用されます

  • validate – Hibernateはテーブルと列が存在するかどうかのみを検証し、存在しない場合は例外をスローします

  • none –この値は事実上DDL生成をオフにします

Spring Bootは、スキーママネージャーが検出されなかった場合、このパラメーター値を内部的にデフォルトでcreate-dropに設定します。それ以外の場合は、noneに設定します。

値を慎重に設定するか、他のメカニズムの1つを使用してデータベースを初期化する必要があります。

5. @Sql

Springは、@Sqlアノテーションも提供します。これは、テストスキーマを初期化してデータを設定するための宣言型の方法です。

@Sqlアノテーションを使用して新しいテーブルを作成し、統合テスト用の初期データをテーブルにロードする方法を見てみましょう。

@Sql({"/employees_schema.sql", "/import_employees.sql"})
public class SpringBootInitialLoadIntegrationTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testLoadDataForTestClass() {
        assertEquals(3, employeeRepository.findAll().size());
    }
}

@Sqlアノテーションの属性は次のとおりです。

  • SQLスクリプトのconfig –ローカル構成。 これについては、次のセクションで詳しく説明します

  • executionPhase –スクリプトを実行するタイミング(BEFORE_TEST_METHODまたはAFTER_TEST_METHOD)を指定することもできます

  • statements – weは実行するインラインSQLステートメントを宣言できます

  • scripts – weは、実行するSQLスクリプトファイルへのパスを宣言できます。 これはvalue attributeのエイリアスです

@Sqlアノテーションcan be used at the class level or the method level。 特定のテストケースに必要な追加データをロードするには、そのメソッドに注釈を付けます。

@Test
@Sql({"/import_senior_employees.sql"})
public void testLoadDataForTestCase() {
    assertEquals(5, employeeRepository.findAll().size());
}

6. @SqlConfig

@SqlConfigアノテーションを使用してconfigure the way we parse and run the SQL scriptsを実行できます。

@SqlConfigはクラスレベルで宣言でき、グローバル構成として機能します。 または、特定の@Sql注釈を構成するために使用できます。

SQLスクリプトのエンコーディングと、スクリプトを実行するためのトランザクションモードを指定する例を見てみましょう。

@Test
@Sql(scripts = {"/import_senior_employees.sql"},
  config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED))
public void testLoadDataForTestCase() {
    assertEquals(5, employeeRepository.findAll().size());
}

そして、@SqlConfigのさまざまな属性を見てみましょう。

  • blockCommentStartDelimiter –SQLスクリプトファイル内のブロックコメントの開始を識別する区切り文字

  • blockCommentEndDelimiter –SQLスクリプトファイルのブロックコメントの終わりを示す区切り文字

  • commentPrefix –SQLスクリプトファイル内の単一行コメントを識別するプレフィックス

  • dataSource –スクリプトおよびステートメントが実行されるjavax.sql.DataSourceBeanの名前

  • encoding – SQLスクリプトファイルのエンコーディング、デフォルトはプラットフォームエンコーディング

  • errorMode –スクリプトの実行中にエラーが発生したときに使用されるモード

  • separator –個々のステートメントを区切るために使用される文字列。デフォルトは「–」です。

  • transactionManager –トランザクションに使用されるPlatformTransactionManager のBean名

  • transactionMode –トランザクションでスクリプトを実行するときに使用されるモード

7. @SqlGroup

Java 8以降では、繰り返し注釈を使用できます。 この機能は、@Sqlアノテーションにも利用できます。 Java 7以下の場合、コンテナ注釈—@SqlGroupがあります。 Using the @SqlGroup annotation, we can declare multiple @Sql annotations:

@SqlGroup({
  @Sql(scripts = "/employees_schema.sql",
    config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)),
  @Sql("/import_employees.sql")})
public class SpringBootSqlGroupAnnotationIntegrationTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testLoadDataForTestCase() {
        assertEquals(3, employeeRepository.findAll().size());
    }
}

8. 結論

この簡単な記事では、schema.sqlファイルとdata.sqlファイルを利用して、初期スキーマを設定し、データを入力する方法を説明しました。 また、@Sql, @SqlConfigおよび@SqlGroupアノテーションを使用して、テスト用のテストデータをロードする方法も確認しました。

このアプローチは基本的で単純なシナリオに適していることに注意してください。高度なデータベース処理には、LiquibaseFlywayなどのより高度で洗練されたツールが必要になります。

コードスニペットは、いつものように、over on GitHubで見つけることができます。