先日(2019/1/31)開催されました JSUG勉強会 2019 その1 の内容をまとめてみました。
Java ORマッパー選定のポイント
[SlideShare Link](https://www.slideshare.net/masatoshitada7/java-or-jsug?ref=https%3A%2F%2Ftwitter.com%2Fi%2Fcards%2Ftfw%2Fv1%2F1090929751462531075%3Fcardname%3Dplayer&autoplay_disabled=true&forward=true&earned=true&edge=true&lang=ja&card_height=130&scribe_context=%7B%22client%22%3A%22web%22%2C%22page%22%3A%22search%22%2C%22section%22%3A%22default_tweets%22%2C%22component%22%3A%22tweet%22%7D&bearer_token=AAAAAAAAAAAAAAAAAAAAAPYXBAAAAAAACLXUNDekMxqa8h%252F40K4moUkGsoc%253DTYfbDKbT3jJPCEVnMYqilB28NHfOPqkca3qaAxGfsyKCs0wRbw&fbclid=IwAR3nUi1c0gunXLMwqG32IRyfwYgMrPwHLpJWaNzvoEYNczBAwqOZOZWWMno )OR マッパーとその分類
- JavaでDBアクセスと言えばJDBC
- JDBCの問題点
- SQLを文字列でプログラム内にべた書きする
- 毎回同じことを書かなければならない
- ResultSetをエンティティに詰め替えるのが面倒
そこでOR マッパーの登場
- RDBのレコードをJavaのオブジェクトに変換する
- SQLを自動発行したり外部ファイルに記述できる
OR マッパーは大きく4(+1)種類
- JDBCラッパー型
- JDBCを薄くラッピングしたもの
- SQLラッパー型
- SQLとクラスの詰替に特化している
- クエリビルダー型
- クラス、メソッドでSQLを書く
- 狭義のORマッパー型
- リレーション重視、SQL自動発行
- Spring Data
- Spring Data JPAがある
- 新たにSpring Data JDBCが登場
JDBCラッパー型
- JDBCを薄くラッピングしただけ
- 使いやすく学習コストが低い
- Spring JDBCなど
Spring JDBC
- Connection,Statementは触らない
- ResultSetからの詰替えのみ開発者が記述する
- Spring のDIコンテナがなくても動く
- BeanPropertyRowMapperクラス
- 列名とプロパティ名が同じものは自動詰替してくれる
- 以外と便利
- JDBCができることは何でもできる
- 集計、バッチ更新、1:Nリレーションを持つクラス
- まとめ
- 使い方が簡単
- SQLはべた書き
- RowMapperの記述は面倒
SQLマッパー型
- SQLとクラスの詰替に特化
- MyBatis,Domaなど
My Batis
- SQLをXMLに記述する
- MapperXMLと1対1のインターフェース
- インターフェースのみ作ればよい
- 条件分岐
<if test="salary != null"> - 不等号の扱いが大変(xmlでは "<" , ">" がかけない)
- を使うとよいが、今度は \ と \ を切り分けるのが大変
Doma
- 2-way SQLが書ける
- SQL 単体でも実行可能
- 今後英語のドキュメントのみになっていく
2-way SQL
- パラメータや条件分岐はコメントで書く
- 2-way SQLが便利だが、アノテーションプロセッサが競合する可能性がある。
クエリビルダー型
- SQLをクラスやメソッドで記述する
- 記述を間違えるとコンパイルエラーになる
- jOOQ,DBFlute
jOOQ
- 検索の例
create
.select(EMPLOYEE.ID)
.from(EMPLOYEE)
.orderby()
- SQLタイプミスの心配はないが、複雑なSQLを再現できるかは不明
ORマッパー型
- JPA
- Java EE 標準のデータアクセスの仕様
- Hibernate を標準化しようとして作られた
- 仕様なので、実装したライブラリが必要
- EclipseLink,Hibernate
- JPQLによる検索
- SQLが書けるが、副問合せなどに制限がある。
- 超重要なのがエンティティの状態
- New,Managed,Detached,Removed状態
- EclipseLinkとHibernateは挙動が違う
- 学習コストが高い
- JPAをなぜ選んだか、と聞くと「標準技術だから」と答える人が多い
JPAを使ってもいい条件
- DBを新規に設計できる、複雑なSQLがない、習熟した人がPJ内にいる、など
- 難易度が高い。避けた方がよい
Spring Data
- 多くのデータアクセス技術を抽象化して、共通のインターフェースを提供する
- CrudRepositoryインターフェース
- RDB向けは、Spring Data JPAのみ
- JPAの複雑さをわかった上で使う必要がある
ORマッパー選定フロー
- おすすめは Spring JDBCか MyBatis
早わかりSpring Data JDBC
[SpeakerDeck Link](https://speakerdeck.com/rshindo/jsug-2019-01 )JPAは難しい
- そこで、Spring Data JDBC
Spring Data JDBCとは
- Spring Data ファミリーに加わった、RDBアクセスの為のライブラリ
- Spring Data JPA のようなRepositoryをJPA抜きで簡単に実装できる。
- シンプルであることがコンセプト
- JDBCTemplateのように何でもできる、という方向ではない。
- キャッシュ、遅延読み込みなどサポートしない
- Entity はPojoでOK (@entity とか不要)
- JdbcTepmlateを直接操作しない
- SQLマッパーよりはORマッパー寄り
- one to many をサポート
Spriong Data JDBC
- getting start
- Spring Boot 2.1.1
- Spring Data JDBC 1.0.4
- saveメソッド…insert or update
アーキテクチャ
- Spring JDBC かMyBatisを選択できる
- JDBCTemplateに対するラッパー
- MyBatisとの連携も可能
- Repositoryインターフェース、xmlファイルを作ればRepositoryが使えるようになる
エンティティの作り方
リポジトリ
- @Queryで任意のクエリを実行できる
- カスタムリポジトリ
できないこと
- ページング、ソート
- PagingAndSortRepositoryはサポートされていない
- メソッド名からクエリを自動生成する機能
- 複合主キーはサポートしていない
- 将来的にできるようになるかも微妙
リレーション
- 関連オブジェクトの永続化操作をサポートしている
- 1対Nの関連をサポート
- N対1、M対Nはサポートしていない
- Spring JDBC実装とMyBatis実装で対応状況が異なる
親子テーブル (1:N)
- 親レコードを削除すると、子レコードも削除される
- 親レコードの更新時、子レコードはDel/Insert
- 社員テーブル、部署テーブルに加えて社員部署テーブルを作る
その他の機能
- Events
- Repositoryの各操作に対してイベントトリガーを仕込むことが可能
- Auditing
- 監査用カラムへの値設定
まとめ
- Spring Data JDBC をおすすめする人
- Repository使いたいけどJPAは使いたくない人
- クエリ書きたくない人
- Spring Data JDBC をおすすめしない人
- クエリ全部書きたい人
- キャッシュや遅延フェッチがほしい人
- 既存のスキーマにマッチしない人
- ナチュラルキーは適さない