Liquibaseを使用してデータベーススキーマを安全に進化させる
1. 概要
このクイックチュートリアルでは、 Liquibaseを使用して、JavaWebアプリケーションのデータベーススキーマを進化させます。
最初に一般的なJavaアプリを見ていきます。また、SpringとHibernateで利用できるいくつかの興味深いオプションについても焦点を当てて見ていきます。
簡単に言うと、Liquibaseを使用する上での核となるのは、 changeLogファイルです。これは、DBを更新するために実行する必要のあるすべての変更を追跡するXMLファイルです。
pom.xmlに追加する必要のあるMaven依存関係から始めましょう。
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.4.1</version>
</dependency>
また、新しいバージョンのliquibase-coreここがあるかどうかを確認することもできます。
2. データベース変更ログ
次に、単純なchangeLogファイルを見てみましょう。
これは、列「address」をテーブル「users」に追加するだけです。
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<changeSet author="John" id="someUniqueId">
<addColumn tableName="users">
<column name="address" type="varchar(255)" />
</addColumn>
</changeSet>
</databaseChangeLog>
変更セットがidとauthorによってどのように識別されるかに注意して、一意に識別され、1回だけ適用できることを確認してください。
これをアプリケーションに接続する方法を見て、アプリケーションの起動時に実行されることを確認しましょう。
3. SpringBeanでLiquibaseを実行する
アプリケーションの起動時に変更を実行する最初のオプションは、SpringBeanを使用することです。
もちろん、他にも多くの方法がありますが、Springアプリケーションを扱っている場合、これは優れた簡単な方法です。
@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog("classpath:liquibase-changeLog.xml");
liquibase.setDataSource(dataSource());
return liquibase;
}
クラスパスに存在する必要がある有効なchangeLogファイルを指していることに注意してください。
4. スプリングブートでLiquibaseを使用する
Spring Boot を使用している場合、Liquibaseに bean を定義する必要はありませんが、liquibase-core依存関係を追加する必要があります。
次に、変更ログを db / changelog / db.changelog-master.yaml に配置するだけで、Liquibaseの移行が起動時に自動的に実行されます。
liquibase.change-log プロパティを使用して、デフォルトの変更ログファイルを変更できます。
liquibase.change-log=classpath:liquibase-changeLog.xml
5. SpringBootでLiquibaseを無効にする
場合によっては、起動時にLiquibase移行の実行を無効にする必要があります。
最も簡単なオプションは、spring.liquibase.enabledプロパティを使用することです。このようにして、残りのすべてのLiquibase構成は変更されません。
Spring Boot2の例を次に示します。
spring.liquibase.enabled=false
Spring Boot 1.xの場合、liquibase.enabledプロパティを使用する必要があります。
liquibase.enabled=false
6. Mavenプラグインを使用してchangeLogを生成します
changeLog ファイルを手動で作成する代わりに、Liquibase Mavenプラグインを使用してファイルを生成し、多くの作業を節約できます。
6.1. プラグインの構成
pom.xmlへの変更は次のとおりです。
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
</dependency>
...
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
</plugin>
</plugins>
6.2. 既存のデータベースからChangeLogを生成します
プラグインを使用して、既存のデータベースから変更ログを生成できます。
mvn liquibase:generateChangeLog
liquibaseのプロパティは次のとおりです。
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
outputChangeLogFile=src/main/resources/liquibase-outputChangeLog.xml
最終結果はchangeLogファイルであり、これを使用して初期DBスキーマを作成するか、データを入力することができます。
これがどのように見えるかです:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog ...>
<changeSet author="John (generated)" id="1439225004329-1">
<createTable tableName="APP_USER">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints primaryKey="true"/>
</column>
<column name="accessToken" type="VARCHAR(255)"/>
<column name="needCaptcha" type="BIT(1)">
<constraints nullable="false"/>
</column>
<column name="password" type="VARCHAR(255)"/>
<column name="refreshToken" type="VARCHAR(255)"/>
<column name="tokenExpiration" type="datetime"/>
<column name="username" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="preference_id" type="BIGINT"/>
<column name="address" type="VARCHAR(255)"/>
</createTable>
</changeSet>
...
</databaseChangeLog>
6.3. 2つのデータベース間の差分からChangeLogを生成します
プラグインを使用して、2つの既存のデータベース(開発と本番など)の違いからchangeLogファイルを生成できます。
mvn liquibase:diff
プロパティは次のとおりです。
changeLogFile=src/main/resources/liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=jdbc:h2:mem:oauth_reddit
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml
referenceDriver=org.h2.Driver
referenceUsername=sa
referencePassword=
そして、生成されたchangeLogのスニペットは次のとおりです。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog ...>
<changeSet author="John" id="1439227853089-1">
<dropColumn columnName="address" tableName="APP_USER"/>
</changeSet>
</databaseChangeLog>
これは、たとえば、Hibernateが開発用の新しいスキーマを自動生成し、それを古いスキーマに対する参照ポイントとして使用できるようにすることで、DBを進化させる非常に強力な方法です。
7. LiquibaseHibernateプラグインを使用する
アプリケーションがHibernateを使用する場合、changeLogを生成する非常に便利な方法を見ていきます。これはliquibase-hibernateプラグインです。
7.1. プラグインの構成
まず、新しいプラグインを構成し、適切な依存関係を使用してみましょう。
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
<dependencies>
<dependency>
<groupId>org.liquibase.ext</groupId>
<artifactId>liquibase-hibernate4</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.3.RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
7.2. データベースと永続エンティティ間の差分からchangeLogを生成します
このプラグインを使用して、既存のデータベース(本番環境など)と新しい永続エンティティの違いからchangeLogファイルを生成できます。
したがって、簡単にするために、エンティティが変更されると、古いDBスキーマに対して変更を生成するだけで、本番環境でスキーマを進化させるためのクリーンで強力な方法が得られます。
liquibaseのプロパティは次のとおりです。
changeLogFile=classpath:liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=hibernate:spring:org.baeldung.persistence.model
?dialect=org.hibernate.dialect.MySQLDialect
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml
referenceUrl はパッケージスキャンを使用しているため、dialogパラメーターが必要であることに注意してください。
8. JPAバディプラグインを使用してIntelliJIDEAでchangeLogを生成します
非HibernateORM(EclipseLinkやOpenJPAなど)を使用している場合、または liquibase-hibernate プラグインのような依存関係を追加したくない場合は、 JPABuddyを使用できます。 ]。 このIntelliJIDEAプラグインは、Liquibaseの便利な機能をIDEに統合します。
差分changeLogを生成するには、プラグインをインストールしてから、JPA構造パネルからアクションを呼び出します。 比較するソース(データベース、JPAエンティティまたはLiquibaseスナップショット)とターゲット(データベースまたはLiquibaseスナップショット)を選択します。
JPAバディは、以下のアニメーションに示すようにchangeLogを生成します:
liquibase-hibernateプラグインに対するJPABuddyのもう1つの利点は、Javaとデータベースタイプ間のデフォルトのマッピングをオーバーライドできることです。 また、HibernateカスタムタイプおよびJPAコンバーターでも正しく機能します。
9. 結論
この記事では、Liquibaseを使用して、JavaアプリのDBスキーマを進化およびリファクタリングする安全で成熟した方法に到達するためのいくつかの方法を説明しました。
これらすべての例とコードスニペットの実装は、GitHubでから入手できます。