VelocityでSQLを使う

以前、SQLテンプレートエンジンってないかなーと考えてたんだけど、Velocityのマクロ使えば必要な機能は簡単に実現できた。
あんまり大した機能じゃないんだけど、アイデアって大事だと思う。コードもごくわずか。100行ちょいだと思う。

JARはここ: velosql-j.jar
ソースはこっち: velosql-j-sources.jar

簡単に使い方説明。
まず実行したいSQLを書きます。今回はhoge.sqlして、クラスパスの通ってるとことにおきます。
hoge.sqlの中身はこんな感じで。

select * from HOGE
where ID = #bind($id)

#bindってのがマクロ。通常のvelocityの機能は当然全て使える。単にデフォルトでbindマクロを用意しただけ。
次にJava部分。

//インスタンスつくってー
Velosqlj velosqlj = new Velosqlj();
//初期化
velosqlj.init();
//デフォルトでクラスパスからテンプレート取得するようにしてます。
Template template = velosqlj.getTemplate("hoge.sql");
//パラメータを作成するためにVelocityContextを作成。
VelocityContext context = new VelocityContext();
context.put("id", "100");
//実行するとSqlDataが帰ってくる。
SqlData data =  velosqlj.renderTemplate(template, context);
//これで実行用のSQLを取得
System.out.println(data.getSql());
//これでパラメータが取れる。
for (Object parameter : data.getParameters()) {
	System.out.println("parameter:"+parameter);
}
//これでログ出力用のSQLを出せる
System.out.println(data.literal());

これだけ。
実行結果はこうなる

select * from HOGE
where ID =  ? 
parameter:100
select * from HOGE
where ID =  '100' 

実際のシステムで使う場合、Velosqljクラスは毎回生成しない。どっかにstaticの定数として保持しとけばいいと思う。

こんな単純な方法でJavaからSQLを生成出来るのに、どうして定番パターンになってなかったんだろう。ショボイから?。いや、たぶんやってる人はいても、あまりにもショボすぎてネットに公開してないだけだろう。
でも、Javaソース内でガリガリSQL書いてる人は、ちょっと取り入れてみないかなぁ。
あ、実際に使う場合はもう少し上位のレベルのAPIを用意しなきゃですね。こいつはかなり低レベルな機能しか用意してないから。