MyBatis Schema Migrationを使ってみる
この記事は Java Advent Calendar -ja 2010 の4日目のものです。
はじめに
継続的な開発では、データベーススキーマも段階的変化に耐えることが求められる。マイグレーション・システムが必要だ。
そこで、MyBatis Schema Migrationというのがあるらしいので試してみた。ほら、Java屋にはおなじみのMyBatisだ。
インストールする
http://code.google.com/p/mybatis/downloads/list?can=3&q=migrations から、「MyBatis Schema Migrations 3.0.2 GA」をダウンロードし、適当な場所に展開し、PATHを通す。
migrate init - 初期設定
プロジェクトのホームがあれば、その下に空のディレクトリを作り、そこでスキーマの管理をするとしよう。空のディレクトリを作ってcdし、「migrate init」コマンドを実行することで、初期の設定ができる。
cd /some/project/home mkdir migration cd migration migrate init
インストールが上手くいっていれば、下のようなメッセージが表示されるはず。
$ migrate init Initializing: /some/project/home/migration/. Creating: environments Creating: scripts Creating: drivers Creating: README Creating: development.properties Creating: bootstrap.sql Creating: 20101216095521_create_changelog.sql Creating: 20101216095522_first_migration.sql Done!
上手くいっていない場合、ちゃんとcdしたかなどを疑おう。俺は3回くらいやった。
DB接続情報の設定
JDBCドライバと、接続情報を設定する。ドライバのjarをmigration/driversにコピーし、migration/environment/default.propertiesに接続情報を記述すればよい。
今回は手軽に、H2データベースを使うが、JDBCであれば恐らくなんでも問題はない。
http://www.h2database.com/html/main.html から「Platform-Independent Zip」をダウンロードして展開、JDBCドライバ(bin/h2-1.3.148.jar)をmigration/driversにペーストする。
migration/environment/default.propertiesに設定を記述する。他のDBMSを使う場合は、usernameとpasswordを含めて適当に設定しよう。
driver=org.h2.Driver url=jdbc:h2:~/migration_test username= password=
さて、これで準備が整った。
migrate status - スキーマの状態を確認
migrate statusコマンドにより、スキーマの状態を確認できる。初期状態では、changelogというテーブルを作成する準備が出来ているようだ。もちろん、これがMigrationの管理用テーブルとなる。
$ migrate status ID Applied At Description ================================================================================ 20101216095521 ...pending... create changelog 20101216095522 ...pending... first migration
「...pending...」とあるのは、未適用状態ということ。とりあえず、適用してみよう。migrate upコマンド。
$ migrate up ========== Applying: 20101216095521_create_changelog.sql ======================= -- Create Changelog -- Default DDL for changelog table that will keep -- a record of the migrations that have been run. -- You can modify this to suit your database before -- running your first migration. -- Be sure that ID and DESCRIPTION fields exist in -- BigInteger and String compatible fields respectively. CREATE TABLE CHANGELOG ( ID NUMERIC(20,0) NOT NULL, APPLIED_AT VARCHAR(25) NOT NULL, DESCRIPTION VARCHAR(255) NOT NULL ) ALTER TABLE CHANGELOG ADD CONSTRAINT PK_CHANGELOG PRIMARY KEY (id) ========== Applying: 20101216095522_first_migration.sql ======================== -- First migration. -- Migration SQL that makes the change goes here.
migrate statusしてみると、pendingではなくなったらしい:
$ migrate status ID Applied At Description ================================================================================ 20101216095521 2010-12-16 19:03:33 create changelog 20101216095522 2010-12-16 19:03:34 first migration
実際のDBの状態を確認すると、changelogというテーブルが作られていて、レコードが2つあることがわかる。
H2の場合、migration/drivers/h2-1.3.148.jarを実行(Finder上でダブルクリックとか)すれば、何となく使えるはず。
migrate new - あらたなバージョンを追加
スキーマを変更したくなった場合、migrate newコマンドを使う。「migrate new "some comment"」のようにコメントを付けると、migration/scriptフォルダ下にsqlファイルの雛形を作ってくれる。
$ migrate new "add table users" Creating: 20101216101815_add_table_users.sql Done!
このファイルに対し、進めた場合と戻した場合、両方のスクリプトを記述する。今回はuserテーブルを追加したいということにしよう。戻す場合は、DROPすることになる。
--// add table users -- Migration SQL that makes the change goes here. CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255) ); --//@UNDO -- SQL to undo the change goes here. DROP TABLE users;
「migrate status」すると、pendingになっていることがわかるはず。「migrate up」で、スキーマを更新しよう。
$ migrate up ========== Applying: 20101216101815_add_table_users.sql ======================== -- add table user -- Migration SQL that makes the change goes here. CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255))
migrate statusしてみると:
$ migrate status ID Applied At Description ================================================================================ 20101216095521 2010-12-16 19:03:33 create changelog 20101216095522 2010-12-16 19:03:34 first migration 20101216101815 2010-12-16 19:27:02 add table users
テーブルの追加だけではなく、既存テーブルにカラムを追加したり、カラムの名前を変更するために新規カラム追加→アップデート→既存カラム削除といった、SQLで実現できる程度に複雑な更新も記述できる。システムの設定情報をレコードで管理している場合、設定情報を更新させたり。
migrate version - 特定のバージョンに変更する
さて、スキーマバージョンを戻したくなった。migrate version
$ migrate version 20101216095522 Downgrading to: 20101216095522 ========== Undoing: 20101216101815_add_table_users.sql ========================= -- @UNDO -- SQL to undo the change goes here. DROP TABLE users
statusを確認:
$ migrate status ID Applied At Description ================================================================================ 20101216095521 2010-12-16 19:03:33 create changelog 20101216095522 2010-12-16 19:03:34 first migration 20101216101815 ...pending... add table users
ペンディングに戻った。
ほか、migrate downコマンドでも進めたり戻したりできる。
さて、これで色々できるぞ。
トラブルシュート
ERROR: Could not create SqlRunner. Cause
migrate statusなどをしたとき、↓のようなエラーメッセージが出る場合がある。
ERROR: Could not create SqlRunner. Cause: org.h2.jdbc.JdbcSQLException: ...
H2データベースの場合、ブラウザのコンソール経由で接続しているはずなので、切断すればよい。切断は上部一番左のアイコンで。
その他
参考
- http://www.mybatis.org/java.html
- MyBatis-3.0.3-Migrations.pdf に今回のこと以上のことが書いてあります。薄い本なので、一読しましょう。
- isbn:9784894715004