プロダクトとしてではなく、ツールとしてdbfluteを使用する(Tableいっぱい編)。とそこから発展
前提
プロダクトとして、dbfluteは導入できないけど、
タイプセーフなSQLを作るためのツールとしてdbflute使ってみよう!という話。
※ログからSQLをひっぱって流用するのを想定
はたして便利なのか?
最近のツールは賢いぞ!
と思うものの、いや・・・自分SQL苦手ですから・・・
UPDATE文とか時々空で書けないですから・・・
というレベルの人にとっては光明となるか!?
まぁ面白そうだということでチャレンジしてみた。
導入や生成なんて、それこそ小1時間もかからずに出来るんだが、
いかんせん、メリット兼デメリットである「コードジェネレータ」という点が、
大量のテーブルを抱えるプロジェクトではネックとなる。
- includeQueryMap.dfprop
- table.except.list.dfprop
を駆使して、生成リソースを減らすものの、どうしても限度があり、
(そもそも、使わないというテーブルなんて、明らかに使わないとかレベルじゃないとこの段階では絞れないフェーズを想定)
この段階で5000を超える生成物があり、
テスト実行時などに非常に動作が重い。
マシンがしょぼかったりするせいもあると思う。
よし!いっそ、生成したらjarにしてしまおうという発想!
対処内容
build-[project].xml
の設定で、ソースディレクトリ以外に出力されるようにする。
torque.java.dir = ../gensrc
build.xmlを用意する。
内容はこんな感じ。(実物は後ほど)
ツールとして利用するdbfluteとしては、
生成物に手を入れることはないと思うんだけど、
一応手を入れられる手段を用意しておく。
純粋なsrcではないソースディレクトリを用意するとよいかも。
今回はsrcにそもまま配置してしまう。
結果
生成されたjarをlibに配置して、クラスパス通して、
テストクラス用意して、
Queryは「投げずに」、cb.toDisplaySql()とかで、SQLを取得。
うーん快適だ・・・
これが、ソースディレクトリに生成ソースが入っていたときとかだと、
気がつくとeclipseがお亡くなりになっていたりしたのを考えると、
build時だけのストレスで済むのは大きいですね。
あとは、SQLの大文字縛りとかだったら、toUpperかませたりして(そんなオプションもありそうだけど)、
エイリアスが「dbflute」なのを置換したりすればきれいな「正しい」SQLの完成です。
(この置換でバグが潜む可能性があるのはいただけないですけどね(^^;)
さーてどうなんだろうね。これがいいことかはご自身の手で確認してみてください。
僕なんかからすると、少なくとも、
SQL書いているというより、
コード書いているという感じがストレスフリーです。
そして、プロダクトとして利用しようよ。。。という思いがストレスフル。
以下buildファイル
クリーンビルド(デフォルト)と
差分ビルドと、
一応後始末タスクを適当に使い分けてください。
テーブル数が少なければ、全部デフォルトでいいと思いますが・・・
<?xml version="1.0" encoding="UTF-8"?> <project name="tool_flute" default="all" basedir="."> <!-- プロパティの定義--> <property name="dist.dir" value="dist"/> <!-- dbfluteの生成物に手を入れる場合に配置するソースディレクトリ サブクラスに手を入れる場合、同じFQDNで配置しておく。 通常のソースディレクトリと同一の必要はない。 --> <property name="src.dir" value="src/main/java"/> <property name="gen.dir" value="gensrc"/> <property name="tmp.dir" value="tmp"/> <property name="tmp.src" value="${tmp.dir}/src"/> <property name="tmp.bin" value="${tmp.dir}/bin"/> <property name="jar.name" value="genflute.jar"/> <target name="prepare"> <mkdir dir="${dist.dir}"/> <mkdir dir="${tmp.dir}"/> <mkdir dir="${tmp.src}"/> <mkdir dir="${tmp.bin}"/> <echo message="生成物をコピー from=${gen.dir}"/> <!-- dbfluteによる生成ファイルをコピー --> <copy todir="${tmp.src}"> <fileset dir="${gen.dir}"> <include name="**/*.java"/> <exclude name="**/test/*"/> </fileset> </copy> <echo message="編集物をコピー from=${src.dir}"/> <!-- 編集したファイルをコピー サブクラスの上書きを想定なので、 overwite="true"とする。(Timestampが古いことが多いと想定) --> <copy todir="${tmp.src}" overwrite="yes"> <fileset dir="${src.dir}"> <include name="**/dbflute/**/*.java"/> <exclude name="**/test/*"/> </fileset> </copy> </target> <!-- "clean"ターゲットは、"compile"ターゲットが次に要求する 配備ホームディレクトリ構造を新規に作り直すために、削除します。 --> <target name="clean"> <!-- tmp.srcは消さない方が、copyに時間を取られなくてよいこともある。 dbfluteによる生成をした場合や、クラスを手動で削除した場合以外は コメントアウト推奨 --> <delete dir="${tmp.bin}" failonerror="no"/> <delete dir="${tmp.src}" failonerror="no"/> <delete dir="${tmp.dir}" failonerror="no"/> <delete dir="${dist.dir}" failonerror="no"/> </target> <target name="compile" depends="prepare"> <!-- UTF-8指定でのコンパイル --> <javac srcdir="${tmp.src}" destdir="${tmp.bin}" encoding="UTF-8" debug="true" debuglevel="lines,vars,source"> <classpath> <fileset dir="lib"> <include name="*.jar"/> <exclude name="${jar.name}"/> </fileset> </classpath> </javac> </target> <!-- build用のディレクトリ等をクリーンにしてビルドを行う。 --> <target name="all" depends="clean,prepare,compile,jar"> <echo message="**********************************************************"/> <echo message="ビルド終了"/> <echo message="jarfile=${dist.dir}/${jar.name}"/> <echo message="**********************************************************"/> </target> <!-- 以前のbuildリソースを利用し、差分でのビルドを行う。 クラスの削除(リネーム含む)がない場合など、こちらを推奨 特にファイル数が多い場合に有効 --> <target name="diffBuild" depends="prepare,compile,jar"> <echo message="**********************************************************"/> <echo message="Diffビルド終了"/> <echo message="jarfile=${dist.dir}/${jar.name}"/> <echo message="**********************************************************"/> </target> <target name="jar" depends="prepare,compile"> <jar jarfile="${dist.dir}/${jar.name}" update="false"> <fileset dir="${tmp.bin}"/> <!--srcを含めない場合、不要。--> <fileset dir="${tmp.src}"/> </jar> </target> <!-- きっちり最後にファイルを削除したい場合 --> <target name="finallize"> <delete dir="${tmp.src}"/> <delete dir="${tmp.bin}"/> <delete dir="${tmp.dir}"/> </target> </project>