説明
概要
データベーススキーマに定義されたオブジェクトをdrop & createし、データをロードすることでデータベーススキーマのマイグレーションを行います。
このタスクを実行する前に、Gen-Ddl によってDDLファイルやダンプファイルが生成されていなければいけません。
処理の流れ
デフォルトの処理の流れを説明します。
Migrateタスクは、まず、現在のデータベーススキーマのバージョン番号をschemaInfoFullTableName属性に指定したテーブルから取得します(テーブルが存在しない場合は0になります)。 次に、移行先のバージョン番号をddlInfoFile属性に指定したテキストファイルから取得します(ファイルが存在しない場合は0になりますが、Gen-Ddlタスクを実行していれば存在するはずです)。 それから、現在のスキーマのバージョン番号に対応するディレクトリを選択し、その直下のdropディレクトリ以下にあるDDLファイルを実行します。 この処理により、古いオブジェクトが削除されます。 その後、移行先のバージョン番号に対応するディレクトリを選択し、その直下のcreateディレクトリ以下にあるDDLファイルの実行とダンプファイルのロードを行います。 この処理により、新しくオブジェクトが作成され、schemaInfoFullTableName属性に指定したテーブルに移行先のバージョン番号が格納されます。 また、ダンプファイルが存在する場合はデータがテーブルにロードされます。 以上で、マイグレーションが完了します。
マイグレーション後にダンプファイルを修正してデータをロードしなおしたい場合は、再度Migrateタスクを実行してください。 この場合、現在のスキーマのバージョン番号と移行先のバージョン番号が同じになりますが、実行される処理の流れはバージョン番号が異なる場合と同様です。 つまり、現在のスキーマのバージョン番号と移行先のバージョン番号が同じであれば、同じバージョンディレクトリ以下のdropディレクトとcreateディレクトリが処理されます。
バージョン番号
データベーススキーマのバージョン番号は、schemaInfoFullTableName属性に指定したテーブルで管理されます。 どのカラムにバージョン番号を格納するかについては、schemaInfoColumnName属性で指定できます。 このバージョン番号は、データベーススキーマがどのDDLのバージョンを使用して作成されたかを示します。
テーブルの作成やバージョン番号の更新は、Migrateタスクにより自動で行われます。
ディレクトリとファイルの処理順序
dropディレクトリとcreateディレクトリどちらを対象にするにせよ、同じ階層に存在するファイルやディレクトリは名前で昇順にソートされ処理されます。 たとえば、dropディレクトリの直下に010-foreignkeyと030-uniquekeyの2つのディレクトリがある場合、010-foreignkey、030-uniquekeyの順番で処理されます。 しかし、もし、それら2つに加え020-sequenceというディレクトリがあれば、順番は、010-foreignkey、020-sequence、030-uniquekeyとなります。
Migrateタスクは、ディレクトリについてはその階層を下へ辿ります。ファイルについては拡張子に従って処理します。
- 拡張子がsqlもしくはddlの場合、データはSQLとみされデータベースに対し発行されます。
- 拡張子がcsvの場合、データはCSV形式のダンプファイルとみなされデータベースにロードされます。
- その他の拡張子を持つファイルについては、何の処理も行われません。
任意のSQLの実行
SQLを記述したファイルをdropディレクトリやcreateディレクトリ以下に配置することで、任意のSQLを実行できます。 ファイルの形式についてはSQLファイル を参照してください。
この機能を利用することで、Gen-Ddl タスクでは生成できないストアドプロシージャ/トリガー/ビューに関するDDLや、データの整合性を確認するためのSQLを実行できます。
たとえば、ビューに関するDDLを実行する場合、ビューの作成と削除のためのDDLをemployeeView.sqlという2つのファイル に記述し、次のように配置できます。
db └─migrate └─0002 ├─create │ ├─... │ └─061-view │ └─employeeView.sql └─drop ├─001-view │ └─employeeView.sql └─...
上記のように配置した場合、employeeView.sqlはディレクトリとファイルの処理順序 で示した順序に従って自動で実行されます。
dropディレクトリやcreateディレクトリ以下に追加したディレクトリやファイルは、Gen-Ddlタスクによる自動コピー の対象になります。
マイグレーションを初めて実行する際の注意点
マイグレーションを初めて実行する際、つまり、バージョン番号0のディレクトリで管理されたDDLを実行する際ですが、 S2JDBC-Genからは知りえない名前の制約(主キー、外部キー、一意キー等)がデータベーススキーマに存在すると、マイグレーションに失敗することがあります。 これは、Gen-Entityタスク を使って既存のデータベーススキーマからエンティティを生成するケースで起こりえます。 Gen-Entityタスクでは、既存のデータベースで管理された制約の名前を取り込むことができないからです
マイグレーションを成功させるためには、既存データベースから不要なオブジェクトをあらかじめ削除しておくか、 バージョン番号0のディレクトリで管理された削除用のDDLを修正して既存の制約名が削除されるように変更してください。
既存のデータベーススキーマを使用せず、新規にS2JDBC-Genを使ってデータベーススキーマを定義していく場合には、問題ありません。
パラメータ
Antタスクへのパラメータを以下に示します。
トップレベルのパラメータ
属性 | 説明 | デフォルト値 | 必須 |
---|---|---|---|
classpathDir | エンティティクラスを含むクラスパスのディレクトリです。このディレクトリはタスクの実行時のクラスパスに含まれている必要があります。 | - | YES |
rootPackageName | ルートパッケージ名です。 | "" | NO |
entityPackageName | エンティティクラスのパッケージ名です。エンティティクラスは、rootPackageNameとこの値をピリオドで連結したパッケージに配置されているとみなされます。 | "entity" | NO |
entityClassNamePattern | このタスクで対象とするエンティティクラス名の正規表現です。 | ".*" | NO |
ignoreEntityClassNamePattern | このタスクで対象としないエンティティクラス名の正規表現です。 | "" | NO |
schemaInfoFullTableName | スキーマのバージョンを管理するテーブル名です。 | "SCHEMA_INFO" | NO |
schemaInfoColumnName | スキーマのバージョンを管理するカラム名です。 | "VERSION" | NO |
migrateDir | マイグレーション用のファイルを管理するディレクトリです。 | "db/migrate" | NO |
ddlInfoFile | DDLのバージョン番号を管理するファイルです。 | "db/ddl-info.txt" | NO |
versionNoPattern | バージョン番号のパターンです。バージョン番号に対応するディレクトリ名に使用されます。 | "0000" | NO |
version | マイグレーション先のバージョンです。ここには、特定の文字列もしくはバージョン番号を表す数値を指定できます。文字列としては、最新のバージョン番号を表す"latest"、現在のデータベーススキーマの次のバージョンを表す"next"、現在のデータベーススキーマの1つ前のバージョンを表す"previous"の3つがサポートされています。数値としては、0以上2147483647以下の値でなければいけません。 | "latest" | NO |
statementDelimiter | SQLステートメントの区切り文字です。 | ";" | NO |
blockDelimiter | SQLブロックの区切り文字です。指定しない場合は、データベースのデフォルトの区切り文字が使用されます。たとえば、SQL Serverでは"go"、Oralce Databaseでは"/"、MySQLでは"/"、DB2では"@"が使用されます。 | - | NO |
ddlFileEncoding | DDLファイルのエンコーディングです。 | "UTF-8" | NO |
dumpFileEncoding | ダンプファイルのエンコーディングです。 | "UTF-8" | NO |
haltOnError | "true"の場合、スキーマを作成するSQLやデータのロードが失敗すると即座にエラーを返します。ただし、スキーマを削除する処理については、エラーが起きても処理を続行します。 | "true" | NO |
loadBatchSize | ダンプファイルのデータをロードする際のバッチサイズです。 | "10" | NO |
transactional | "true"の場合、単一のトランザクションとして実行します。 | "false" | NO |
genDialectClassName | S2JDBC-Genのダイアレクトインタフェースの実装クラス名です。ここに指定するクラスはorg.seasar.extension.jdbc.gen.dialect.GenDialectインタフェースを実装している必要があります。指定しない場合はS2JDBCのダイアレクト に対応したデフォルトのクラスが使用されます。 | - | NO |
configPath | JdbcManagerのコンポーネント定義を含む設定ファイルです。このタスクの実行に使用されます。 | "s2jdbc.dicon" | NO |
env | 環境名です。 | "ut" | NO |
applyEnvToVersion | バージョンディレクトリに環境名を適用する場合"true"を指定します。trueを指定すると、通常のバージョンディレクトリよりも環境名つきバージョンディレクトリに存在するダンプファイルを優先してロードします。 | "false" | NO |
jdbcManagerName | JdbcManagerのコンポーネント名です。接続先のデータベースはJdbcManagerのコンポーネント名によって決まります。 | "jdbcManager" | NO |
factoryClassName | S2JDBC-Genの公開されたインタフェースの実装を作成するファクトリのクラス名です。S2JDBC-Genをカスタマイズする場合に独自のファクトリクラスを指定できます。ここに指定するクラスはorg.seasar.extension.jdbc.gen.internal.factory.Factoryインタフェースを実装している必要があります。 | "org.seasar.extension.jdbc.gen .internal.factory.FactoryImpl" |
NO |
commandInvokerClassName | S2JDBC-Genのコマンドを呼び出すクラスの名前です。コマンドの呼び出し前後で任意の処理を実行したい場合に指定します。ここに指定するクラスはorg.seasar.extension.jdbc.gen.command.CommandInvokerインタフェースを実装している必要があります。 | "org.seasar.extension.jdbc.gen .internal.command.CommandInvokerImpl" |
NO |
classpath | このタスクを実行する際のクラスパスです。 | - | classpathrefが指定されていない場合YES |
classpathref | このタスクを実行する際のクラスパスの参照です。 | - | classpathが指定されていない場合YES |
例
マイグレーション先のバージョン番号を指定する
デフォルトでは、マイグレーション先のバージョン番号は最新の番号、つまりddlInfoFile属性に指定されたテキストファイルで管理する番号になります。 最新のバージョン番号ではなく、任意のバージョン番号を指定するには、version属性を使用します。 現在よりも古いバージョン番号を指定することも可能です。
次の例では、マイグレーション先のバージョン番号に15を指定しています。
<migrate classpathDir="build/classes" rootPackageName="examples" version="15" classpathRef="classpath" />
バージョン番号に対応するバージョンディレクトリはあらかじめ存在していなければいけません。 version属性には、バージョンディレクトリ名ではなくバージョン番号を指定することに注意してください。
トランザクション内でマイグレーションを実行する
transactional属性に"true"を指定すると、マイグレーションの処理がトランザクション内で実行されます。 マイグレーションに失敗した場合は、ロールバックにより変更が元に戻ります(ただし、RDBMSがトランザクション内でのDDL実行をサポートしていなければいけません)。
<migrate classpathDir="build/classes" rootPackageName="examples" transactional="true" classpathRef="classpath" />
環境名つきバージョンディレクトリ以下のファイルを優先する
applyEnvToVersion属性に"true"を指定すると、環境名つきバージョンディレクトリ以下に同名の相対パスで表されるファイルがあれば、そちらが優先されるようになります。 設定例は次の通りです。
<migrate classpathDir="build/classes" rootPackageName="examples" applyEnvToVersion="true" env="ut" classpathRef="classpath" />
環境名つきバージョンディレクトリとは、バージョン名と環境名を#で連結したディレクトリのことです。 次の図で言えば、0001#utがバージョンディレクトリになります。
db └─migrate ├─0001 │ └─create │ ├─010-table │ │ ├─employee.sql │ │ └─address.sql │ │ │ ├─040-dump │ │ ├─employee.csv │ │ └─address.csv │ │ │ └─050-foreignkey │ └─0001#ut └─create ├─010-table │ └─employee.sql │ └─040-dump └─employee.csv
この例では、employee.sqlやemployee.csvについては0001#utディレクトリ以下のものが使用され、 0001ディレクトリ以下にあるemployee.sqlやemployee.csvは参照されません。 address.sqlやaddress.csvについては通常のバージョンディレクトリ以下にあるものが使用されます。
環境名つきバージョンディレクトリ以下のダンプデータは、Dump-Dataタスク により作成できます。