JSUG勉強会 参加レポート

先日（2019/1/31）開催されました [JSUG勉強会 2019 その1](https://jsug.doorkeeper.jp/events/86027?error_code=4201&error_message=User%20canceled%20the%20Dialog%20flow#_=_) の内容をまとめてみました。

# Java ORマッパー選定のポイント
<img src="http://image.slidesharecdn.com/jsugor-mapper-190131110611/95/slide-1-1024.jpg" width=66%>
[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では "<" , ">" がかけない）
    - <!CDATA>を使うとよいが、今度は \<if> と \<!CDATA> を切り分けるのが大変  

### 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

<img src="https://qiita-image-store.s3.amazonaws.com/0/65426/92f6475f-3b1d-6f13-4185-fc4464a312a9.png" width=66%>
[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が使えるようになる
 
### エンティティの作り方
  - JPAと同様にテーブルと１対１で作る
  - @Entityは不要
  - 主キーに@idをつける
  - 引数付きコンストラクタにも対応
  - setterも不要。
  - エンティティをイミュータブルにすることも可能
 
### リポジトリ
  - @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 をおすすめしない人
    - クエリ全部書きたい人
    - キャッシュや遅延フェッチがほしい人
    - 既存のスキーマにマッチしない人
    - ナチュラルキーは適さない