JavaでRDBにアクセスするなら、
大きくこの二つの選択肢があるでしょう。
- JPA
- ORMの仕組み
- Javaのオブジェクトを使って情報の永続化(データ保存)や情報の取得をするもの
- 複雑な情報取得のためにJPQLというSQLに似た書き方もできる
- JPA自体は仕様で実装物としてはHibernateが有名(Hibernateの機能をJavaが仕様として取り込んだ)
- Mybatis
- ORMというよりSQLマッピングの仕組み
- SQLをJavaではない外部ファイルに書くことができる
- SQLの結果やバインドパラメータ ⇔ JavaのBeanの間で自動詰替えをしてくれる
私は初学者やほとんどの開発プロジェクトでMybatisの採用を薦めています。
その理由について個人的な意見を記載します。
ただ、JPAは正直あまり使ってないので見当違いがあるかもしれません。
JPAのいいところ
単一テーブルへのアクセスが簡単
単一テーブルや単純な親子関係のテーブルの結合ぐらいなら、とてもシンプル書けるので使いやすいです。
単純な更新系処理(INSERT文UPDATE文DELETE文)はめっちゃラクチンです。
JPAの嬉しくないところ
SQL自動生成がブラックボックス
JPAではSQLが自動生成なので実際にどんなSQLが動いているのか把握しづらいです。
ログ出力すれば見れますが個人的には読みづらいと思っています。
参考:
- https://blog.tagbangers.co.jp/2015/09/08/how_to_display_hibernate_sql_parameters
- https://ice-black.hatenablog.com/entry/2018/04/29/164233
無駄な情報取りすぎ(結合テーブルの情報)
結合する情報をすべて取ってくるのは無駄なメモリを使うことになるかなと思います。
特定項目のみの更新しんどい
Entity単位の更新で、基本的には全項目更新します。
SQLのように指定されていない項目は上書きされないという安心感がありません。
サブクエリ(副問い合わせ)が使いづらい
使えないわけではないけど正直SQLよりしんどいです。
複雑なクエリはSQLツールで試しまくって準備するはずなので、できればそのまま使いたいです。
単純なものでもSELECT UPDATEとかSQL1発で実行したいこととかあるじゃないですか。
メンテナンス性悪い ※これが一番の問題
ほとんどの設計者やプログラマがテーブルをもとにデータが実際に正しく取得できるかをSQLツールなどで試しているはずです。
頭の中だけで組み立てられる強者は少ないですよね。
せっかくSQLツールで試したSQLをわざわざjavaコードやJPQLに変換して書くのは非効率的と考えています。
頑張って一度JPAで書いたとしても不具合がある度にSQLに書き換えてSQLツールで試してまたJPAに書き換え・・・つらすぎます。。
このメンテナンス性の悪さが最も致命的と考えています。
あとから参画した人が手直しするのもMybatisでSQL書かれてる方が把握しやすいしメンテナンスしやすいと思います。
学習コスト高い
「SQLを知らなくても使える」「SQL学習がつらいので」という人もいますが、それは簡単なシステムに限る話かなと思います。
実際には複雑な情報アクセスの必要があり、SQLからは逃げられないです。
結果的にSQLは学習することになるはずです。
情報系エンジニアとしてSQLは必須なのでどっちみち勉強することになりますが、
JPAを使うとなるとSQL + JPAのJavaでの書き方 + JPQLを学ぶことなるので学習コストが高いと思います。
JPAはEJB仕様から独立した仕様とされているようですが、
EJBまで把握しようとするとさらに難易度が高くなりそうです。
EJB使うプロジェクトは最近はあまり見かけないので仕事でも触れる機会ないですからね・・・
JDBCではなくMybatisを使う理由(箇条書き)
- Javaコード内にSQLを混ぜないので、修正時にSQLツールで試しやすい(メンテナンス性高い)
- とはいえ、動的SQLだと、そのままコピーしてSQLツールでは試せないのはつらいところ
- 動的SQL書きやすい(Javaコードにif文条件で文字列結合しながらの動的SQL本当につらい)
- 「SQLの結果やバインドパラメータ ⇔ JavaのBeanの間で自動詰替え」がとても嬉しい
- JDBCだととても面倒くさい部分をカバーしてくれている
総じて
単純なSELECTやINSERT/UPDATE/DELETEをわざわざ書く必要があっても、
これらを書くのは難しいわけではないし
複雑なSQLはタダでもつらいのにさらにJPAに変換して使うのに苦労するぐらいなら
全部SQLで書くことを選びます。
また、SQLはかなり利用頻度の高い技術なので
どのプログラム言語を学ぶ初学者にもおすすめしたいところです。
おまけ
以前、INSERT/UPDATE/DELETEはHibernateを使って、
SELECTはMybatisを使ってくださいというルールにしたことがあります。
結果、プロジェクトでは混乱が起きました。(猛反省)
とくにHibernate利用の部分を一元管理する動きになって、
数百もあるテーブルを一人が管理することになり高負荷になった上に各機能ごとの都合に合わせられなって
結局各機能ごとにSQLを書いてしまうという残念な結果になりました。
失敗した経験から言いたいことはひとつ、
「混ぜるな危険」
です。