注意
私は Java に詳しい自信も RDB に詳しい自信もありません。内容に責任も基本的に負いません。
なぜこの記事を書くか
筆者は Java での Web サービス開発に携わるエンジニアだが、普段何気なく使っている(実は業務では NoSQL が多くそもそも使ってないのだが) ORM などのライブラリについて少し調べているときに、自分が思った以上にデータベースとの接続周りについて疎いことに気づいたので、まとめてみようと思った。
JDBC
まずはここから。JDK 1.1 で登場。
Java からデータベースにアクセスするための標準 API。この「標準」というのは各 JVM のベンダ間で差異のないインタフェースだという意味。
以下のドライバ、ドライバマネージャを通じてアクセスするので、JDBC API はデータベース間で差異はない。JDBC という仕組み全体で、JVM ベンダ・RDB の差異を吸収していると言える。
JDBC ドライバ
各データベースに対して実際に JDBC API を実装しているコネクタのようなもの。例えば MySQL 用、MariaDB 用のドライバがあるということになる。
ググるとわかるが、4種類の接続の方法があるが、それについては一旦割愛する。現在は主に TYPE 4 (Pure Java のドライバである)は主流だとされている。
JDBC ドライバマネージャ
上記ドライバを管理して、アプリケーションから接続するための管理者の役割をする。ユーザが使う場合はこいつに JDBC ドライバを指定してやる。
Connection Pooling (CP)
この文脈におけるコネクションプーリングとは、Java アプリケーションとデータベース間の接続をプールして使いまわす仕組み。
本来はこれに関してはプログラミング言語依存の話ではないし接続先もデータベースに限らないのだが、実際にコネクションプーリングと言ったらアプリケーションとデータベース間の接続のことを指すことが多いと思う。
主に知られているのは、 Tomcat などのアプリケーションサーバに付属したコネクションプーリングライブラリや、Commons DBCP、HikariCP といった専用ライブラリを利用する方法っぽい。すごく簡単に言うと JDBC の Connection オブジェクトを使いまわすことができるようにするラッパーである。
CP の目的(というかCPによって得られる効果といったほうが近いのか)は主に2つあって、
- コネクションの永続化
- 同時接続数の節約
1はクライアント視点で接続の入り切りは少し重い処理なのだということ(RDBMSによってはサーバ側もという話らしい。今は流石にそんなことなさそうだが、、)。2はどちらかというとアプリケーションでたくさんの処理がデータベースを使うような処理をする際は断続的なことが多いので、うまいことあいてるやつを使いまわしてサーバ側の負荷下げようね、って話かなと思う。
Object/Relation Mapper (ORM)
要は RDB の「行」と Java などの「オブジェクト」をマッピングするためのライブラリ。言うても JDBC を使っても ORM なのではという言説もあるみたい。
Hibernate, MyBatis などが知られている。ORM 自身には CP の仕組みはないので、hibernate-HikariCP など組み合わせて使うことが多いと思う。先程の CP が JDBC を接続管理の視点からラップしているのに対し、こちらは利用勝手の側面からラップしていると言っていいと思う。
Java Persistence API (JPA)
Java で RDB を使ったアプリケーションを開発する際のフレームワーク、ということになっているらしい。API とはいうものの、どうやらマッピングを外部記載したりするメタデータなどの部分も総称するみたいだ。それはもはや実装に近いのでは・・?という気もするが。あとは JPQL という SQL ライクな言語で、Java オブジェクトを操作するというのも要素の一部だ。
JPA 2.0 までは Java EE の一部だったらしい。
狭義の JPA、つまり API specification が規定された理由だが、JDBC が(正確には JDBC ドライバマネージャが)データベース間の差異を吸収するならば、こちらは ORM 間の差異を吸収する。要は、様々な ORM 実装がいろんな仕様になってしまうと利用側は差し替えしにくいので、共通の API 仕様を決めてしまい、それを実装するようにしましょう、ということっぽい。ただし、各 ORM は独自機能を持っている場合もあり、完全に1-on-1で対応しているわけではないことに注意。
有名な実装には Hibernate ORM や EclipseLink がある。
なお、ORM の定義にもよるが、MyBatis などを ORM と分類する向きもある。当然 MyBatis は JPA を実装したものではない。
おまけ: Spring JDBC, Spring Data JPA
Spring JDBC
https://stackoverflow.com/questions/9469643/difference-between-spring-jdbc-vs-plain-jdbc
まあこれもざっくりいうと JDBC をより簡単に使えるようにしたラッパーだと思う。ORM といってもいいかも。
Spring Data JPA
https://stackoverflow.com/questions/16148188/spring-data-jpa-versus-jpa-whats-the-difference
https://stackoverflow.com/questions/42470060/spring-data-jdbc-spring-data-jpa-vs-hibernate
JPA を実装した ORM をさらにラップして Spring アプリケーションから簡単に使えるようにしたもの。これもラッパー。
感想
なんでも抽象化されているので、抽象化って、確かに綺麗だけど学習コストはやっぱりあがるなあ。コンピュータ難しいなあ。