Apache Derbyで新規データベースにテーブルを自動構築する簡単な方法
新規データベース作成後の処理
Apache Derbyを埋め込みモードで使う場合、指定したパス上にデータベースが存在しない場合、接続URLのオプションとして、自動的に作成するように指示することができる。
たとえば、以下のような接続URLである。
DriverManager.getConnection("jdbc:derby:memory:myDb;create=true").close();
※ 上記指定のインメモリデータベースは、前の状態など存在しないので、当然、新規作成のオプションは必須となろう。
ただし、この方法では、データベースは自動的に作成されるが、アプリケーションを動作させるに必要なテーブルや初期マスタデータなどが存在しない。
これらは、アプリケーションが自分で作成しなければならない。
これを簡単に実現するには、以下のような手順となる。
- 接続URLのオプションとして「create=true」を指定し、データベースが未存在ならば自動作成するように指示する。
- コネクションを取得したらDatabaseMetaDataで、定義されているテーブルを取得する
- テーブルが定義されていなければ、対話ツールijのクラスのPublic API「runScript」を呼出し、DDLを記述したスクリプトを読み込ませる。
- 用意するDDLのスクリプトは
テータベース上の定義済みテーブル一覧の取得方法
// データベースのAPPスキーマに登録されているテーブル一覧 HashSet<String> existTableName = new HashSet<String>(); DatabaseMetaData dbMeta = conn.getMetaData(); ResultSet rs = dbMeta.getTables(null,"APP","%",null); // 大文字 try { while (rs.next()) { String tableName = rs.getString("TABLE_NAME"); existTableName.add(tableName); } } finally { rs.close(); }
Apache Derbyを組込みモードでつかう場合、スキーマは「APP」となる。
システム定義のテーブルは列挙する必要ないので、APPスキーマ限定でテーブル名を取り出しておく。
対話ツールijのクラスの利用
クラスパスの指定
以下の3つのjarをクラスパスに通す必要がある。
- derby.jar 本体
- derbytools.jar 対話ツールijが含まれる
- derbyLocale_ja_JP.jar 日本語リソース
runScriptの実行方法
InputStream inp = new BufferedInputStream( new FileInputStream(ddlScript)); try { // ijのrunScriptを使用してスクリプトを一括ロードする. ByteArrayOutputStream bos = new ByteArrayOutputStream(); int ret = ij.runScript(conn, inp, "MS932", bos, "UTF-8"); // 結果のログへの書き込み String msg = new String(bos.toByteArray(), "UTF-8"); log.info("load script(numOfFailed=" + ret + ") output=" + msg); } finally { inp.close(); }
※ ijという小文字のクラス名なので注意。(runScriptはstaticメソッドである。)
ij上でrunコマンドでスクリプトを流した場合と同様に、スクリプトの途中でエラーが発生してもスクリプトは最後まで流れる。
また、戻り値として、エラーの発生回数が返される。
ただし、不明なエラーが発生した場合は-1が返される。
よって、runScriptの戻り値が0以外ならば何らかの問題が発生していることを示す。
エラーの発生回数しか把握できないので、なにがエラーになったかはわからない。
しかし、runScriptコマンドを何回かに分けて呼び出すことで、エラーの発生場所と、それによる対処を決めることはできるかもしれない。(たとえば、drop/createなら、dropでエラーになっても無視して、createが全て成功すれば良い。)