MyBatis Migrationでテーブルスキーマの構成管理をする



今回関わったプロジェクトで、テーブルスキーマの構成管理を行うのにMyBatisMigrationを使ったため、備忘録もかねて利用方法を残しておく。

## 機能紹介

### マイグレーションツールとは？

テーブルスキーマを管理するツール。
どの環境にどこまでのSQL適用したかわからなくなるのを防いでくれる。
Java系ではFlyway,Liquibaseなどが有名。


### なぜ導入したのか？

テーブル数、スキーマ変更ともに多いプロジェクトだったため、
評価で利用したDB状態を本番環境で手で作り上げるのは不安があったから。
（手作業だと絶対リリースミスすると思っていた。


### なぜMyBatisMigrationなのか？

FlywayやLiquibaseも調べたが、同一スキーマに自分たちの管理外のテーブルが含まれている場合でも"安心して"使えるのがMyBatisだったことが最大の理由。

なぜ安心できないかというと、
flywayやLiquibaseはコマンド一発でスキーマの全テーブルDROP可能だから(,,ﾟДﾟ)ﾏｼﾞﾃﾞｰ


そんなの実行する人いないでしょとは思いつつも、そんな機能があるものを導入したくはない。
そこでMyBatisMigrationになった。


## セットアップ

[MyBatisMigrationのGithub](https://github.com/mybatis/migrations/releases)からダウンロードして展開。
こんな感じの構成になっている。

```
$ tree
.
├── bin
│   └── migrate
└── lib
    ├── mybatis-3.2.4.jar
    └── mybatis-migrations-3.2.0.jar

```

### migrateコマンドのパスを通す

具体的な手順は割愛。以降は設定されている前提で記載している。


### migrate init

適当なディレクトリで実行すると、設定ファイルや変更履歴管理テーブルのcreate文などが作成される

```
$ migrate init
------------------------------------------------------------------------
-- MyBatis Migrations - init
------------------------------------------------------------------------
Initializing: .
Creating: environments
Creating: scripts
Creating: drivers
Creating: README
Creating: development.properties
Creating: bootstrap.sql
Creating: 20141211083812_create_changelog.sql
Creating: 20141211083813_first_migration.sql
Done!

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 2s
-- Finished at: Thu Dec 11 17:38:13 JST 2014
-- Final Memory: 3M/123M
------------------------------------------------------------------------
```

```
$ tree
.
├── README
├── drivers
├── environments
│   └── development.properties
└── scripts
    ├── 20141211083812_create_changelog.sql
    ├── 20141211083813_first_migration.sql
    └── bootstrap.sql
```


### development.properties（DB接続定義）

　構成管理したいDBスキーマへの接続情報を設定。管理したいDBスキーマにあったものを設定

```
## JDBC connection properties.
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:XE
username=user
password=password
```

### development.properties（変更履歴管理テーブル名）

　これを使い分けることで同一スキーマで複数プロジェクトが同居した場合にも対応

```
# Name of the table that tracks changes to the database
changelog=table_change_log
```

### driverの準備

接続したいDBに接続するためのJDBCドライバを格納。もちろんDB接続定義の記載と合ったものを。詳細は割愛。ググりましょう。

### スキーマ変更履歴管理テーブルの作成

migrate init で作成した20141211083812_create_changelog.sqlを実行することで作成されるため、MyBatisMigrationを実行すればOK。


まずは状態確認。

```
$ migrate status

ID             Applied At          Description
==================================================================
20141211083812    ...pending...    create changelog
20141211083813    ...pending...    first migration
```

ファイル名の先頭の時刻をIDとして管理しているのがわかる。
20141211083812_create_changelog.sql
~~~~~~~~~~~~~~
 　↑これがID


pendingとなっているものをすべて適用したい場合

```
$ migrate up
```

create changelogのみ実行したい場合

```
$ migrate ver 20141211083812
```

を実行する。




## はじめてのMigration

以下のコマンドを実行することでMigrationファイル名ができる。
これを編集する

```
$ migrate new
```


```
-- // First migration.
-- 以下に適用したいSQLを記載する

create table ・・

-- //@UNDO
-- 以下に上記で適用したものを元に戻すSQLを記載する（記載しなくてもいい）

drop table ・・

```


実は ```migrate new``` で作成したファイルではなく、同一の形式で手で作成したファイルもツールは認識してくれている。適用順さえ意識しておけば特に問題はない。

### 実行

pendingのものがすべて実行される

```
$ migrate up
```

### 元に戻す

1段階だけ元に戻す（@UNDOが実行される）

```
$ migrate down
```


## まとめ

正直なところ管理は面倒だが、リリースがもれる不安はなくなった。
ちゃんと管理できていない状態なら導入を検討してみてはどうでしょう。

まだ実際に試してはいないけど、
本番リリースと同時に最新のSQLファイルの@UNDOをSQLエラーが発生する状態にしておけば
ツールが消すことも回避できそう（消そうとするとエラーになるので）


### (参考)よく使うコマンドリファレンス


| コマンド          | 用途
|:-----------------|:----------------------------
| migrate up       | 最新の状態にまで一気に進める     
| migrate down     | 一世代前までDB変更を元に戻す    
| migrate ver [ID] | [ID]適用後の状態にする           
| migrate status   | 現在の状態を表示する         



### (参考)Flyway,Liquebase

[JavaのDBマイグレーションツールを試してみた](http://shanon-tech.blogspot.jp/2013/08/javadb.html)

[StackOverflow - DBマイグレーションツール: Liquibase と Flyway の比較議論]
(http://qiita.com/scova0731/items/a0c634f4a374ec8b1c9a)