はじめに
Kotlin + Spring Boot + Gradleで作成したアプリにマイグレーションツールであるFlywayを導入する手順を説明します。
なおデータベースにはMySQLを用い、Docker上に立てます。
1. プロジェクトの作成
Spring initializrでは以下のように設定しました
2. DockerでMySQLのDBを生成
プロジェクトのルート配下に以下のような構成でDocker用のディレクトリとファイルを作成
.
├── docker/
├── db/
└── docker-compose.yml
docker-compose.ymlの中身
version: '3'
services:
# MySQL
db:
image: mysql:8.0.22
ports:
- "3306:3306"
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: mysql
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./db/data:/var/lib/mysql
- ./db/my.cnf:/etc/mysql/conf.d/my.cnf
- ./db/sql:/docker-entrypoint-initdb.d
dockerディレクトリに移動
$ cd docker
コンテナを立ち上げる
$ docker-compose up -d
正常に立ち上げっているか確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69bb5c657441 mysql:8.0.22 "docker-entrypoint.s…" 10 seconds ago Up 10 hours 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
コンテナ内に入る
$ docker exec -it mysql /bin/bash
DBにアクセス
mysql -h 127.0.0.1 --port 3306 -uroot -pmysql
exampleという名前のデータベースを作成
mysql> create database example;
3. Flyway導入
プロジェクトとMySQLの接続情報設定のためapplication.ymlを以下のように記述
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/example?characterEncoding=utf8
username: root
password: mysql
driverClassName: com.mysql.jdbc.Driver
build.gradle.ktsにプラグイン、依存関係を追加
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.6.3"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
id("org.flywaydb.flyway") version "8.2.0" // 追加
kotlin("jvm") version "1.6.10"
kotlin("plugin.spring") version "1.6.10"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("mysql:mysql-connector-java:8.0.23") // 追加
implementation("org.flywaydb:flyway-core") // 追加
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
// 追加
flyway {
url = "jdbc:mysql://127.0.0.1:3306/example"
user = "root"
password = "mysql"
}
4. マイグレーションファイルを作成
src > main > resources 配下に db > migration ディレクトリを作成し、migrationディレクトリ配下にマイグレーション用の拡張子(.sql)のファイルを作成する。
今回は V1.0.0__user.sql
というファイルを作成。
このファイルにマイグレーションした時に実行されるSQLを記述します。
※ファイル名はV<バージョン>__<任意の名前>.sql
のように命名規則があります。
CREATE TABLE user (
id bigint NOT NULL,
email varchar(256) UNIQUE NOT NULL,
password varchar(128) NOT NULL,
name varchar(32) NOT NULL,
role_type enum('ADMIN', 'USER'),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
マイグレーションを実行
flywayのtaskが実行できるか確認
$ ./gradlew tasks
出力されたログの一覧に以下のような記載があれば実行可能
...省略
Flyway tasks
------------
flywayBaseline - Baselines an existing database, excluding all migrations up to and including baselineVersion.
flywayClean - Drops all objects in the configured schemas.
flywayInfo - Prints the details and status information about all the migrations.
flywayMigrate - Migrates the schema to the latest version.
flywayRepair - Repairs the Flyway schema history table.
flywayUndo - Undoes the most recently applied versioned migration. Flyway Teams only.
flywayValidate - Validate applied migrations against resolved ones (on the filesystem or classpath) to detect accidental changes that may prevent the schema(s) from being recreated exactly. Validation fails if differences in migration names, types or checksums are found, versions have been applied that aren"t resolved locally anymore or versions have been resolved that haven"t been applied yet
...省略
flywayMigrate
でマイグレーションの実行。BUILD SUCCESSFUL のログが出れば成功
./gradlew flywayMigrate
ちゃんとテーブルが作成されてるか確認
以下のようになれば成功。
mysql> use example;
省略
mysql> show tables;
+------------------------------+
| Tables_in_attendance_manager |
+------------------------------+
| flyway_schema_history |
| user |
+------------------------------+
mysql> show columns from user;
+-----------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------------------+------+-----+---------+-------+
| id | bigint | NO | PRI | NULL | |
| email | varchar(256) | NO | UNI | NULL | |
| password | varchar(128) | NO | | NULL | |
| name | varchar(32) | NO | | NULL | |
| role_type | enum('ADMIN','USER') | YES | | NULL | |
+-----------+----------------------+------+-----+---------+-------+
ハマりポイント
MySQLとFlywayプラグインのバージョンに相性があるようです。
相性が悪いと、マイグレーション実行時にエラーになります。