4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kotlin + Spring Boot + Gradle にFlywayを導入する

Last updated at Posted at 2022-02-06

はじめに

Kotlin + Spring Boot + Gradleで作成したアプリにマイグレーションツールであるFlywayを導入する手順を説明します。
なおデータベースにはMySQLを用い、Docker上に立てます。

1. プロジェクトの作成

Spring initializrでは以下のように設定しました
スクリーンショット 2022-02-06 16.18.17.png

2. DockerでMySQLのDBを生成

プロジェクトのルート配下に以下のような構成でDocker用のディレクトリとファイルを作成

.
├── docker/
    ├── db/
    └── docker-compose.yml

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を以下のように記述

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にプラグイン、依存関係を追加

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のように命名規則があります。

V1.0.0__user.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プラグインのバージョンに相性があるようです。
相性が悪いと、マイグレーション実行時にエラーになります。

参考

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?