DDL / DMLの管理

開発時における、DDLやDMLの管理方法について記載します。

以下のサンプルコードの動作確認環境については、 動作確認環境と依存ライブラリについて を参照してください。

DDLの管理

DDLの管理として、バージョン管理が可能なマイグレーションツールであるFlywayについて記載します。 Flyway の基本的な使用方法については、以下を参照してください。

Spring BootはFlywayをサポートしており、アプリケーションの起動時に FlywayのMigrateコマンド を自動実行します。 Flywayのその他のコマンドや、 アプリケーションの起動時ではなく任意のタイミングでFlywayのMigrateコマンドを実行したい場合は、FlywayのMaven Pluginを使用する事で実行が可能です。

参考情報

警告

サンプルコードに設定されているFlyway Maven Pluginを実行すると、使用しているH2のバージョンがサポートされていない旨の警告が出力されます。

[WARNING] Flyway upgrade recommended: H2 2.1.214 is newer than this version of Flyway and support has not been tested. The latest supported version of H2 is 2.1.210.

サンプルコードではSpring Bootのバージョン管理に則ったバージョンを使用していますが、そのバージョン管理上でこの問題が発生しています。 Spring BootのバージョンアップによりFlywayのバージョンが上がれば解消されるため、サンプルコードではバージョンを独自に設定することはせず、Spring Bootで管理しているバージョンのままとしています。

DMLの管理

初期データやテストデータ等のDMLの管理として、DDLと同じようにFlywayを使用する方法があります。 ただ、開発者がテスト時に手動や別のツール等でデータを投入するといった運用をする場合、Flywayではデータのみをクリーニングする機能が存在しないので注意が必要になります。

例えば、Flywayで管理しているデータを投入する前に重複するデータを手動で投入してしまっていた場合、FlywayのMigrateコマンドが失敗してしまいます。そういった事態を避けるために、開発者が手動でデータを削除しなければいけない等、運用が煩雑になることがあります。

そのような状況でDMLを管理する方法の1つとして、ここでは任意のディレクトリに格納されているSQLファイルを実行できる SQL Maven Plugin を使用する方法について記載します。[1]

Tip

テストデータをFlywayで管理したい場合は、プロファイルを使用する方法等がありますので、 9.5.1. Execute Flyway Database Migrations on Startup を参考にしてください。

Flyway Maven Plugin / SQL Maven Plugin の設定例

pom.xml
<build>
  <plugins>
    <!--
    application.propertiesから設定値をロードするプラグインです。
    データベースの接続先情報を、application.propertiesから取得するために使用します。
     -->
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>properties-maven-plugin</artifactId>
      <version>1.1.0</version>
      <executions>
        <execution>
          <phase>initialize</phase>
          <goals>
            <goal>read-project-properties</goal>
          </goals>
          <configuration>
            <files>
              <file>${project.basedir}/src/main/resources/application.properties</file>
            </files>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <!--
    FlywayのMaven Pluginです。
    サンプルアプリケーションでは、「generate-resources」フェーズで「migrate」を実行するように設定しています。
    なお、デフォルト設定ではクラスパス配下のdb/migration配下にSQLファイルを格納します。
     -->
    <plugin>
      <groupId>org.flywaydb</groupId>
      <artifactId>flyway-maven-plugin</artifactId>
      <dependencies>
        <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <version>${h2.version}</version>
          <scope>runtime</scope>
        </dependency>
      </dependencies>
      <configuration>
        <url>${spring.datasource.url}</url>
        <user>${spring.datasource.username}</user>
        <password>${spring.datasource.password}</password>
      </configuration>
      <executions>
        <execution>
          <id>db-migration</id>
          <phase>generate-resources</phase>
          <goals>
            <goal>migrate</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <!--
    SQL Maven Pluginです。
    サンプルアプリケーションでは、「process-test-resources」フェーズで「execute」を実行するように設定しています。
    なお、SQLファイルはsrc/test/data配下に格納する設定にしています。
     -->
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>sql-maven-plugin</artifactId>
      <version>1.5</version>
      <dependencies>
        <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <version>${h2.version}</version>
        </dependency>
      </dependencies>
      <configuration>
        <driver>org.h2.Driver</driver>
        <url>${spring.datasource.url}</url>
        <username>${spring.datasource.username}</username>
        <password>${spring.datasource.password}</password>
        <autocommit>false</autocommit>
        <onError>continue</onError>
        <fileset>
          <basedir>${project.basedir}/src/test/data</basedir>
          <includes>
            <include>*.sql</include>
          </includes>
        </fileset>
        <orderFile>ascending</orderFile>
      </configuration>
      <executions>
        <execution>
          <id>data-load</id>
          <phase>process-test-resources</phase>
          <goals>
            <goal>execute</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

サンプル全体は sql-management-sample を参照してください。