まえがき
以下、長い駄文が控えていますので、御託はいいからサンプルコードを見たい!という方はこちらを御覧ください。
ちなみに、リンク切れしていたり、情報が古くなっていたので、以前書いた Hibernate4を使ったJPA を、Hibernate5を使ったJPAとして、アップデートしました。
まえがき2(駄文の始まり)
Hibernate5を使ったJPAで、Hibernate 5を使って、JPA 2.1のAPI経由でRDBへのCRUDを行ったのですが、ORMを使っていていつも思うこと。
- DBのスキーマとオブジェクトを対にする必要ってなくて、SQLの結果とオブジェクトが対になっていればよくないか?
- SQLって、ロジックそのものに埋め込まれるべきではなくて、きちんと特定のオブジェクト(所謂 DataAccessObject)に隠蔽されるべきではないか?
後者はよく行われているが、前者は、JPAなどにも見られるように、そこまでやられていない。
むしろ、SQLそのものが隠蔽(というか自動生成)されていて、DBのテーブルと対となっている場合が多い(ORMがObject Relation Mappingだから当然と言われそうだが)
しかし、DBのスキーマを変えて、ORMでマッピングされるオブジェクトと、それを使うロジックそのものが影響を受ける(ロジックで使用しているカラムの追加削除なら、それに応じた処理が追加・変更・削除されるからいいとしても、SQLでしかいじらないようなカラムの場合はどうするの?という)
個人的な意見
これは、極めて個人的な意見ではあるのだが、SQLそのものと、その入出力をマッピングするロジックは、ある程度は開発者が意識すべきで、単純にSQLを発行するだとか、SQLのクエリへの変数のバインドなどは、ゴリゴリロジック書いたり、ツール使って吐き出すのではなく、動的に発行されればいいんでないの?
で、そもそも、ロジックが意識するのは、データベースのスキーマと対になったオブジェクトではなくて、SQLのクエリとのインタフェースじゃないのか?と
JDBIとは?
そんな想いを胸に秘めながら(笑)、DropwizardのGetting Startedを読んでいたら、JDBIなるものを発見し、試しに使ってみたところ、上述した不満を尽く解決してくれていて、同じことを考える方が居るものだと感銘を受けて、隠れファンとなりました:p
環境
今回は以下の環境にて開発しています。
- JDK8
- H2(インメモリDBとして使いやすいので、別途、DBMSをローカルに入れる手間がないので、サンプルコードを書くときに使っています。JDBI自体は、JDBCドライバがあれば、他のRDBMSでも動きます。MySQLとかでも動かしたことあるので)
- JDBI
- Gradle(ここ重要。あまり、他のサンプルコードでGradleを使っているものが見受けられなかったので)
- TestNG(好みでしょう。アノテーション変えればJUnitでも動く程度のテストコードしか書いてません)
- Eclipse + TestNGプラグイン(すみません。実は、Gradleのtestが動くかわかりません。Eclipseから動かしてます)
サンプルコード
冒頭に記述したものがそれです。
https://github.com/poad/examples/tree/master/jdbi-examples