jOOQのDB方言変換機能を使ってみる
jOOQまとめがあるので参照されたい
jOOQではDSLを使ってSQLを表現するJavaオブジェクトを構築し、指定されたデータベースに対する実際のSQL文字列を生成する。
DSLを使い、各方言のSQLを生成させる
次は同じ意味のSQLを各方言で出力させる例だ。単純に「select * from a」の結果行の10行目から20行を取得する。
※なお、SQL文字列の取得だけで、実際のDB操作は行わないのでコネクションはnullで良いようだ。
Arrays.stream(new SQLDialect[] { SQLDialect.MYSQL, SQLDialect.FIREBIRD, SQLDialect.DERBY }).forEach(d-> {
DSLContext ctx = DSL.using((Connection)null, d);
System.out.println(
d + ":" + ctx.selectFrom(table("a")).limit(10, 20).getSQL(ParamType.INLINED));
});
出力結果は以下になる。
MYSQL:select * from a limit 20 offset 10
FIREBIRD:select * from a rows (10 + 1) to (10 + 20)
DERBY:select * from a offset 10 rows fetch next 20 rows only
このように、jOOQのDSLによるSQL表現を使うことにより、サポート済のDB用のSQL方言を出力させることができる。
※jOOQの有料バージョンでは、Oracle等の有料DB向けの出力ができる。
各方言のSQLを別方言に変換するウェブ
上はDSL表現からの方言出力だったのだが、方言文字列から別の方言文字列に変換する試みもされている。もちろん、試してみたところでは、これは完全ではない。「ある程度は」というところだ。実際に以下で試すことができる。
実際に前項で得られたFirebird用の文字列を入力してみるとエラーになってしまう(2019/6現在)。
ところが、Firebirdの以前の仕様を入力してみると、今度はうまく行っている。
各方言のSQLを別方言に変換するプログラム
前述のようにこの機能は完全ではないのだが、実際にプログラムでこれを行わせる方法としては以下だ。
ここでは、最初の10行を取得するFirebirdの古い仕様を入力としている。
Arrays.stream(new SQLDialect[] { SQLDialect.MYSQL, SQLDialect.FIREBIRD, SQLDialect.DERBY }).forEach(d-> {
DSLContext ctx = DSL.using((Connection)null, d);
Query query = ctx.parser().parseQuery("select first 10 * from a");
System.out.println(ctx.render(query));
});
結果は以下になる。
MYSQL:select * from a limit 10
FIREBIRD:select * from a rows (0 + 1) to (0 + 10)
DERBY:select * from a offset 0 rows fetch next 10 rows only
※ウェブ版では、入力方言を指定するコンボがついているが、プログラム上では入力方言を指定する方法は見つからなかった。出力方言のみを指定できる。