$30 off During Our Annual Pro Sale. View Details »

2023/4/27 Java仕様勉強会: Jakarta Persistence

2023/4/27 Java仕様勉強会: Jakarta Persistence

2023/4/27 Java仕様勉強会で使用したスライドです。

spec
https://jakarta.ee/specifications/persistence/3.1/

Eclipse Starter for Jakarta EE
https://start.jakarta.ee/

The Jakarta® EE Tutorial
https://eclipse-ee4j.github.io/jakartaee-tutorial/

Satoshi Seto

April 27, 2023
Tweet

More Decks by Satoshi Seto

Other Decks in Technology

Transcript

  1. 瀬戸
    1
    4月27日Java仕様勉強会
    Jakarta Persistence
    レッドハット株式会社
    2023.04.27

    View Slide

  2. 2
    ▸ 名前:瀬戸 智
    ▸ Twitter: @megascus
    ▸ ServletとかJPAあたりが好きで、一時期個人でServletとJPAのJavaDocを翻訳していた。
    ・ そのあとPleiadesの人が機械翻訳をしてくれるようになったので現時点では意味なし。
    自己紹介

    View Slide

  3. Jakarta Persistence
    とは(1/7)
    3

    View Slide

  4. 4
    ▸ Jakarta EE サーバーが実装しているリレーショナルデータベースアクセスの仕様
    ▸ Java SEでも使用可能
    ▸ データアクセスとともにObject-Relational Mappingも行う
    ▸ 現在の最新版はJakarta Persistence 3.1 (Jakarta EE 10)
    ▸ 昔はJava Persistence API(JPA)という名前だった
    ▸ この資料ではJakarta Persistence だと長いのでJPAと呼びます!
    Jakarta Persistenceとは

    View Slide

  5. 5
    ▸ データベースとの接続方法等、JDBCに含まれているもの
    ▸ RDB以外のデータベースとのやり取り
    ・ 実際にはJPA仕様の一部APIを利用したNoSQL製品用ライブラリも存在する
    ▸ どのRDBに対応しているかどうか
    ・ 実際に使用できるRDBの種類は実装依存
    Jakarta Persistenceの仕様に含まれていないもの

    View Slide

  6. 6
    ▸ Javaのクラスとデータベースのテーブルのマッピングを行う
    ▸ JDBCでのResultSetからのオブジェクトへの詰め替え処理(もしくは逆)を省力化する
    ▸ テーブルがマッピングされたJavaのクラスをエンティティと呼ぶ
    Object-Relational Mapping(ORM)
    Employeeクラス(@Entityアノテーション付き)
    EMPLOYEEテーブル
    String employeeId
    CHAR(8) EMPLOYEE_ID
    String firstName
    VARCHAR(100) FIRST_NAME
    String lastName
    VARCHAR(100) LAST_NAME
    Date hireDate
    DATE HIRE_DATE
    String jobCode
    CHAR(8) JOB_CODE
    long salary
    DECIMAL(12,0) SALARY

    View Slide

  7. 7
    https://jakarta.ee/release/10/
    https://docs.google.com/presentation/d/1zv84tq7SGRIpzPfxFQVAdVNT2jQvadjt/edit#slide=id.p8
    (参考)Jakarta EE 10に含まれている仕様

    View Slide

  8. 8
    ▸ 今はEclipse FoundationsのJakarta EEワーキンググループで公開されています。
    https://jakarta.ee/specifications/persistence/3.1/
    JPAの仕様

    View Slide

  9. 9
    ▸ SQLを直接使う場合に比べてデータベース
    の差異を隠してくれるため、プログラムの
    可搬性に優れる
    ▸ JDBCに比べてボイラープレートを削減す
    ることができ、実装の効率が良くなる
    ▸ キャッシュ等の仕様が組み込まれており、
    性能面で利点がある
    ▸ 可搬性を考えるとSQLを直接使う場合に比
    べて使用できる機能が減る
    ▸ JDBCよりも暗黙の動作が多いため、初心
    者に理解しにくい
    ▸ キャッシュ等の仕様があるためJPA以外と
    の併用が難しい
    JPAを使うメリット・デメリット
    メリット デメリット

    View Slide

  10. 10
    ※一部ライブラリは最新版の仕様に準拠していない場合があります。
    JPAを実装したライブラリ
    ▸ Hibernate
    ▸ EclipseLink
    ▸ OpenJPA
    ▸ DataNucleus
    ▸ その他
    Jakarta EE Server
    ▸ WildFly
    ▸ Open Liberty
    ▸ Eclipse GlassFish
    ▸ Payara Community
    ▸ Apache TomEE
    ▸ その他
    JPAの仕様と実装
    JPAはただの仕様なので、実際に使用するときは実装が必要

    View Slide

  11. 11
    ▸ Jakarta Persistence(JPA)はJakarta EEのデータベースアクセスの仕様
    ▸ 使うことで実装の効率化が可能、データベース間の移植性も上がる
    ▸ 仕様なので別途使用する実装を選ぶ必要がある
    ここまでのまとめ

    View Slide

  12. Jakarta EEサーバー
    でのJPA (2/7)
    12

    View Slide

  13. 13
    ▸ Jakarta EEサーバーはJPA以外にも多数の機能が入っており、それらが密接に結合してい

    ▸ Jakarta EEサーバー上とJava SEで動かすときで挙動が違う場合があるので注意
    ・ 特にトランザクションとか
    ▸ この資料は原則としてJakarta EEサーバー上での説明
    Jakarta EEサーバー上のJPA

    View Slide

  14. 14
    アプリケーションはJDBCを使って直接DBへアクセスを行う。
    JDBCを使った場合のデータベースアクセス
    クライアント
    アプリケーションサーバー データベース
    業務ロジック
    DAO
    DAO
    DAO
    DAO
    DAOの中にはSQLが書かれ
    ていて実行される
    JDBC
    HTTP(S)

    View Slide

  15. 15
    アプリケーションは永続化ユニット(JPAのAPI)を通じて永続化コンテキストへアクセスする。
    JPAの永続化コンテキストは必要に応じてデータベースへアクセスする。
    JPAを使った場合のデータベースアクセス
    クライアント
    アプリケーションサーバー データベース
    業務
    ロジック
    JDBC
    HTTP(S)
    永続化
    コンテキスト
    永続化
    ユニット
    永続化
    ユニット
    永続化
    ユニット
    永続化
    コンテキスト
    永続化
    コンテキスト

    View Slide

  16. 16
    ▸ 一般的に遅いと言われるデータベースへのアクセスを最小限にすることが出る
    ・ すでに取得されているデータの2重取得は行わない
    ▸ 他の拡張機能による処理のフックを可能にする
    ・ キャッシュライブラリ、監査等
    エンタープライズアプリケーションで必要な性能を確保し、
    アプリケーションの拡張性を担保できるようになる!
    永続化ユニットとコンテキストを使うことのメリット

    View Slide

  17. 17
    ▸ プログラマーが期待したタイミングでデータベースとの同期(=SQLの発行)が行われるわけ
    ではないので、JDBCを直接使用している場合と挙動が変わる
    ・ ただし、データベースとの同期を強制的に行わせることもできる
    ▸ キャッシュを共有できない複数のアプリの間でデータの同期をとるのが難しい
    ・ Java以外で作られたシステムと同期をとる必要がある場合に問題になる
    永続化ユニットとコンテキストを使うことのデメリット
    最新のデータがあるの
    はデータベースではなく
    永続化コンテキスト

    View Slide

  18. 18
    ▸ Persistence Contextが日本語に翻訳された時に表記ゆれが発生している
    ・ 永続化コンテキスト
    ・ 永続性コンテキスト
    ・ 永続コンテキスト
    ・ 持続性コンテキスト
    ※製品によってはドキュメント内でブレている場合もあり。
    この資料ではPersistenceから始まるものは永続化~で統一しています。
    (補足)永続化コンテキストの表記ゆれ

    View Slide

  19. 19
    ▸ JPAを使用する場合、永続化コンテキストを通じてデータベースにアクセスする
    ▸ 永続化コンテキストはキャッシュ等のデータベース高速化手法を提供する
    ▸ 永続化コンテキストの挙動のためSQLを直接発行する場合と使い勝手が変わる
    ここまでのまとめ

    View Slide

  20. JPA使用の準備(3/7)
    20

    View Slide

  21. 21
    すべてのJakarta EEサーバーで共通で以下のような感じ(実装依存を含む)
    ▸ JDBCドライバーをサーバーに登録
    ▸ DBコネクションをデータソースとしてコネクションプールに登録
    ▸ war内の/WEB-INF/classes/META-INF/persistence.xmlに永続化ユニットを定義
    ・ 永続化ユニットは永続化コンテキストに問い合わせるためのAPI
    ▸ 定義した永続化ユニットをCDI を使用して取得
    ・ 取得できるクラス(インターフェース)はjakarta.persistence.EntityManager
    JPAを使い始めるまでの設定

    View Slide

  22. 22
    ※Jakarta EEサーバー以外も含めるとTomcatが1位
    ▸ 2022年のJakarta EE Serveyで一番使われていたJakarta EEサーバー(※)
    ・ https://www.wildfly.org/
    ▸ WildFly Quickstarts (作り始める時のベースとしても便利)
    ・ https://docs.wildfly.org/27/Quickstarts.html
    ※一部wildfly固有の設定が含まれているため
    他のAPサーバーでは動かないことがあります。
    WildFly(実装依存部分の説明に使用)

    View Slide

  23. 23
    アプリケーションサーバー個別の方法でJDBCドライバーを登録する
    ※wildflyの場合はxmlに直接書くか、CLI、GUI管理ツールで設定可能
    JPAを使い始める①-JDBCドライバーの登録

    View Slide

  24. 24
    ▸ アプリケーション (war/ear)内にJDBCドライバーのjarを含めても動く場合もあるが、一般
    的にデータベース接続はアプリケーションサーバーが管理するものなので、アプリケーシ
    ョンサーバー側で管理をしないと不具合が発生することがある
    ▸ CI/CDとかで一緒に管理したい場合に注意
    ▸ 詳細は各アプリケーションサーバーのドキュメントを参照してください
    (注意)JDBCドライバーの管理

    View Slide

  25. 25
    アプリケーションサーバー固有の設定ファイルでコネクションプールを登録
    ※wildflyの場合はxmlに直接書くか、CLI、GUI管理ツールで設定可能
    JPAを使い始める②-コネクションプールの追加

    View Slide

  26. 26
    定義は https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd
    Warファイル内 /WEB-INF/classes/META-INF/persistence.xml
    ※versionは3.0
    JPAを使い始める③-persistence.xmlの追加

    View Slide

  27. 27
    設定に成功している場合、デプロイしたときにログが出力される
    ※ログの内容は使用しているAPサーバー、ライブラリによって違います
    ログの確認

    View Slide

  28. 28
    Jakarta EEのDependency Injectionの機能を使用してEntityManagerを取得する
    EntityManagerが永続化ユニットの実装インターフェース
    JPAを使い始める④-CDIでEntityManagerを取得

    View Slide

  29. 29
    JPAを使用するためには以下の手順を踏む必要がある
    ▸ APサーバー固有の方法でJDBCドライバを登録
    ▸ APサーバー固有の方法でデータソースを設定
    ▸ persistence.xmlをアプリケーションに含める
    ▸ CDIを使用してEntityManagerのインスタンスを取得
    ここまでのまとめ

    View Slide

  30. JPAを使用する(4/7)
    30

    View Slide

  31. 31
    ▸ @jakarta.persistence.Entityアノテーションを付けたJava Beansクラス(※)を準備する。
    ▸ このクラスはエンティティと呼ばる。
    ▸ このエンティティのインスタンスが
    データベースの内容と同期化される。
    ※Java Beansはいわゆるアクセサ(getter/setter)のついた、パラメーターをメンバー変数として持ち、デフォルトコンス
    トラクタのあるクラス
    エンティティの準備

    View Slide

  32. 32
    エンティティをインスタンス化し、パラメーターをセットしたうえで、EntityManagerの
    persistメソッドを呼び出して永続化コンテキストに紐づける。
    ただし、このタイミングでSQLが発行されるわけではない。
    永続化コンテキストは別途適切なタイミングでデータベースへアクセスする。
    CDI管理bean内でEntityManagerを操作して永続化する

    View Slide

  33. 33
    アプリケーションは永続化ユニット(EntityManager)で永続化コンテキストへアクセスする。
    JPAの永続化コンテキストは必要に応じてデータベースへアクセスする。
    永続化コンテキストに紐づけられたエンティティはデータベースと同期化される。
    (再)JPAを使った場合のデータベースアクセス
    クライアント
    アプリケーションサーバー データベース
    業務
    ロジック
    JDBC
    HTTP(S)
    永続化
    コンテキスト
    永続化
    ユニット
    永続化
    ユニット
    永続化
    ユニット
    永続化
    コンテキスト
    永続化
    コンテキスト

    View Slide

  34. 34
    値をセットしてからpersistを呼び出す persistを呼び出してから値をセットする
    次の二つのコードは同じ結果をもたらす
    永続化コンテキストに紐づけられているエンティティへの変更は自動的に永続化される

    View Slide

  35. 35
    ▸ エンティティが永続化コンテキストに紐づいている場合、
    エンティティへの変更内容がデータベースに反映される
    ▸ エンティティが永続化コンテキストに紐づいていない場合、
    エンティティへの変更内容がデータベースに反映されない
    覚えておいてほしいエンティティの状態

    View Slide

  36. 36
    エンティティに関わる永続化コンテキストを操作するメソッド
    説明
    メソッド
    新しいエンティティを永続化コンテキストにエンティティを紐づける
    persist()
    (新しい、もしくは一度紐づけが解除された)エンティティを永続化コンテキストに紐づける
    merge()
    永続化コンテキストからデータを取得する(データベースからデータを取得する)
    find()
    エンティティと永続化コンテキストとの紐づけを解除する、このエンティティへの変更はデータ
    ベースと同期がとられなくなる
    detach()
    永続化コンテキストにデータを削除するように指示する
    remove()
    永続化コンテキストとデータベースの内容を同期する(=SQLを発行してデータベースを更新
    する)
    flush()
    エンティティの内容をデータベースの内容で更新する
    refresh()
    永続化コンテキストの内容をクリアし、永続化コンテキストに紐づいているエンティティすべて
    の紐づけを解除する
    clear()

    View Slide

  37. 37
    ▸ トランザクション境界の外側にいったエンティティは自動的に永続化コンテキストの紐づ
    けから解除される
    ▸ Jakarta EEサーバーではデフォルトでCDI 管理beanの内部はトランザクション境界内とな

    ▸ トランザクション境界は設定で変更できるので、挙動がおかしいと感じたらトランザクシ
    ョン境界内かを確認する必要がある。
    ・ 特に大規模プロジェクトでは基盤チームが設定変更していることが多い・・・・
    (補足)トランザクションの内側と外側を分けるトランザクション境界

    View Slide

  38. 38
    ▸ JPAではエンティティを使用してデータベースのデータを操作する
    ▸ エンティティを操作するためにはEntityManagerを使用する
    ▸ 永続化コンテキストに紐づいているエンティティはデータベースに同期される
    ▸ 永続化コンテキストに紐づいていないエンティティはデータベースに同期されない
    ※複数のエンティティを同時に取り扱うこともできます。
    ここまでのまとめ

    View Slide

  39. エンティティの作り方
    (5/7)
    39

    View Slide

  40. 40
    ▸ @jakarta.persistence.Entityアノテーションを付けたJava Beansクラス
    ▸ このエンティティのインスタンスがデータベースの内容と同期化される
    ▸ エンティティの1インスタンスがテーブルの1行に相当する
    エンティティ
    Employeeクラス
    EMPLOYEEテーブル
    String employeeId
    CHAR(8) EMPLOYEE_ID
    String firstName
    VARCHAR(100) FIRST_NAME
    String lastName
    VARCHAR(100) LAST_NAME
    Date hireDate
    DATE HIRE_DATE
    String jobCode
    CHAR(8) JOB_CODE
    long salary
    DECIMAL(12,0) SALARY

    View Slide

  41. 41
    ▸ Javaのクラス定義とリレーショナルデータベースのテーブル定義は考え方が違うため、1対
    1でマッピングさせると最適にならない場合がある
    ・ いわゆるインピーダンスミスマッチ
    ▸ JPAでは複数のテーブルを一つのエンティティに、もしくは一つのテーブルを複数のエン
    ティティに分割できる等、柔軟な定義が可能になっている
    ・ 一つのテーブルと一つのクラスを単純に関連付けさせるのはActive Recordパターンと呼ばれる
    エンティティによるテーブルとのマッピング

    View Slide

  42. 42
    ※継承関係がある場合にクラスの属性をテーブルにどうマッピングするのかの指定
    @Entity @Inheritance(strategy=JOINED)
    public class Customer { ... }
    @Entity
    public class ValuedCustomer extends Customer { ... }
    共通フィールドを一つのテーブルにまとめてサブクラス固有のフィールド用のテーブルを別途作るか、
    クラスごとにテーブルを作成するか、すべての属性を一つのテーブルにまとめるか、の三択。
    検索時の性能に影響する。
    エンティティ/テーブルのマッピングで使用するアノテーション例
    説明
    アノテーション
    エンティティをマッピングするテーブルの名前や、テーブルが持つユニーク制約を指定する
    @Table
    複数のテーブルを一つのエンティティにマッピングしたい場合にして
    @SecondaryTable
    @SecondaryTableを複数個使いたい場合に使用
    @SecondaryTables
    サブクラスをどうやってテーブルにマッピングするかを指定する(※)
    @Inheritance
    @Entity @Inheritance(strategy=JOINED)
    public class Customer { ... }
    @Entity
    public class ValuedCustomer extends Customer { ... }

    View Slide

  43. 43
    フィールド/カラムのマッピングで使用するアノテーション例
    説明
    アノテーション
    マッピングするカラムの名前や長さ、null許容等の情報を入力する。JPAのエンティティから
    テーブルを生成する場合の情報としても使用する。
    @Column
    プライマリーキーに指定する。エンティティに必須。※あとで説明
    @Id, @EmbededId
    Enumをデータベースに保存したい時に序数で保存するか文字列で保存するか指定する。
    @Enumerated
    フィールドとデータベースのカラムの型変換を行うクラスを指定する。※あとで説明
    @Convert
    Blob/Clobをマッピングするときに指定。
    @Lob
    日付型をマッピングするときに指定。
    @Temporal
    楽観ロックに使用する。※後で説明
    @Version
    フィールドをデータベースにマッピングしないことを指定する。(デフォルトでマッピングされる)
    @Transient
    ※これらのアノテーションはフィールドもしくはgetterに適用できます。

    View Slide

  44. 44
    ▸ 永続化コンテキスト(JPA)はプライマリーキー(@Id, @EmbeddedId)でエンティティを判別する
    ・ 同じ値を持っていたら同じエンティティとして扱う
    ▸ プライマリーキー(主キー)の値は変更できない
    ▸ JPAが生成する単一のシステム生成キー(サロゲートキー、代理キー)の使用が推奨
    ・ 何も設定しなかった場合、ユーザーが入力しなくても自動採番される
    エンティティの一意性を判別するプライマリーキー(主キー)

    View Slide

  45. 45
    ▸ 複数のカラムに@Idをつけ、”名前、型、フィールドの数が全て一致するクラス”を別途作成する
    ▸ @IdClassでそのクラスを指定する
    複合主キー(1)

    View Slide

  46. 46
    ▸ @Embeddableアノテーションを使うことで複数のカラムを一つのクラスにまとめることができる
    ・ 複合主キー以外に住所や郵便番号等、複数に分割されてるけど一つとして扱いたいものに使う
    ▸ 主キーの指定に@Idの代わりに@EmbeddedIdを使用する。
    ▸ 検索用のIdClassと実際に使用するエンティティが分かれなくなるので、こちらが推奨
    複合主キー(2)

    View Slide

  47. 47
    ▸ JPAの型の変換はJDBCに従うが、Converterを作成することで自由に行うことができる
    ▸ コンバータークラスに@Converter(autoApply = true)を付ける(すべてのエンティティに影響する)か、
    falseにしてカラムにつけた@Convertアノテーションで指定する
    ▸ コンバータークラスはAttributeConverterクラスを実装する
    JavaとDBの型変換を行うConverter

    View Slide

  48. 48
    ▸ エンティティに@Versionのついたフィールドが含まれている場合、楽観ロックの機能が有効になる
    ・ エンティティが他のトランザクションで更新されていた場合に、上書き保存しようとしたときに
    エラーにする機能
    ▸ ウェブ業務システムの場合、複数人が同時に更新した場合に先勝ちにするのが一般的なので、基本的
    に@Versionを付けることになる
    ▸ @Versionの付けられたフィールドはシステムが自動的にインクリメントする
    ▸ @Versionが付けられるフィールドはint、Integer、short、Short、long、Long、 Timestamp
    更新時の楽観ロック

    View Slide

  49. 49
    ▸ エンティティ内のメソッドに特定のアノテーションを付けていると永続化コンテキスト内でイベント
    が発生したときにメソッドを実行することができる
    ・ 初めて永続化された時や更新された時などにイベントが発火
    ▸ 作成日付や更新日付を入れる場合に便利
    ▸ エンティティクラスに@EntityListenersアノテーションを付けることで
    イベントリスナーを外部クラスで定義することもできる
    エンティティのイベントリスナー

    View Slide

  50. 50
    ▸ 関係するエンティティを設定し、他のエンティティのデータを取得することができる
    ・ いわゆるRDBでの参照整合性制約(外部キー制約)の張られた先のデータを取得できる
    ▸ 二つのエンティティの関連が二つのテーブルにマッピングされるとは限らない
    ▸ カラムに以下のアノテーションを付けることで関連先のエンティティを指定できる
    ・ @OneToOne (1対1)
    ・ @OneToMany (1対多)
    ・ @MenyToOne (多対1)
    ・ @ManyToMany (多対多、中間テーブルも生成される)
    ▸ 相手が”多”の場合はエンティティのコレクションになる。
    複数のエンティティのリレーションシップ(関係)

    View Slide

  51. 51
    ▸ 1対多、多対多(@OneToMany、@ManyToMany)の場合、デフォルトで遅延ロードが有効になっている
    ・ 大量のデータを意図せずに読み込んでしまう可能性があるため
    ▸ 遅延ロードが有効な場合、アクセスするまでデータがデータベースから取得されない(場合がある)。
    ・ ただし、エンティティが永続化コンテキストに紐づいているときのみ
    ・ 永続化コンテキストに紐づいていないときは例外が発生する
    ▸ fetch=FetchType.EAGERで遅延ロードを無効化できる(慣れるまでは推奨)
    リレーションシップ(関係)の遅延ロード

    View Slide

  52. 52
    ▸ エンティティは@jakarta.persistence.Entityアノテーションを付けたJava Beansクラス
    ▸ エンティティはテーブルとのマッピングを表す
    ▸ アノテーションでテーブル、カラムとのマッピングのカスタマイズが可能
    ▸ エンティティ間のリレーションシップ(関係)を表現できる
    ここまでのまとめ

    View Slide

  53. クエリーでの
    大量のデータ処理(6/7)
    53

    View Slide

  54. 54
    JPAではJakarta Persistence Query Language(JPQL)とCriteria APIの2種類のクエリーを独自
    サポートしている
    ▸ JPQLはエンティティを対象としたSQLライクなクエリー言語で、SQLを使用したことが
    ある人なら直感的に利用できる
    ▸ Criteria APIはStream APIのようにJavaのオブジェクト・メソッドをくみ上げることでクエ
    リーを構築することができ、型安全にクエリーが作れるのが特徴
    ※両方で同じことができます。
    JPA用の2種類のクエリー言語
    こちらのみを説明

    View Slide

  55. 55
    ▸ プライマリーキー以外でのデータの検索
    ▸ 大量データの取得、更新、削除
    JPQLを書く主なユースケース

    View Slide

  56. 56
    ▸ Select句
    例) select e from Employee e where e.id = :id
    ▸ Update句
    例) update Employee e set e.salary = e.salary * 1.01
    ▸ Delete句
    例) delete Employee e where e.salary > 10000
    JPQLの種類

    View Slide

  57. 57
    select e from Employee e where e.id = :id
    JPQLの書き方の基本
    SQLではテーブルに対してクエリーを書く / JPAではエンティティに対してクエリーを書く
    検索対象とするエンティティのクラス名(もしくは
    @Entityのnameで指定した値)
    JPAではバインド引数に名前を指定できる。
    もしくは”?1”のように序数でも指定が出来る。
    (JDBC:SQLの?の代わり)
    SQLでのカラムの代わりにJPAではエンティティを返す

    View Slide

  58. 58
    select e.department
    from Employee e where e.id = :id
    JPQLの書き方-リレーションシップでの取得
    SQLではテーブルに対してクエリーを書く / JPAではエンティティに対してクエリーを書く
    エンティティのリレーションシップを利用して
    他のエンティティを返すこともできる
    ※departmentはEmployeeエンティティから@ManyToOneで紐づいている

    View Slide

  59. 59
    select e from Employee e
    where e.department.id = :id
    JPQLの書き方-リレーションシップでの検索
    SQLではテーブルに対してクエリーを書く / JPAではエンティティに対してクエリーを書く
    エンティティのリレーションシップを利用して
    他のエンティティの条件で検索する

    View Slide

  60. 60
    select e.name from Employee e
    where e.id = :id
    JPQLの書き方-エンティティ以外を返す
    SQLではテーブルに対してクエリーを書く / JPAではエンティティに対してクエリーを書く
    従業員名のStringが返る

    View Slide

  61. 61
    select avg(e.salary) from Employee e
    JPQLの書き方-集計関数
    給与の平均

    View Slide

  62. 62
    select e from Employee e
    where e.salary > all (
    select m.salary from Manager m
    where m.department = e.department)
    JPQLの書き方-サブクエリー
    相関サブクエリーも使えます
    all、any、someのいずれか

    View Slide

  63. 63
    select e from Employee e
    where type(e) in (Exempt, Contractor)
    JPQLの書き方-特定の型のエンティティの検索
    ポリモーフィズムを利用している場合
    Employeeのなかで
    サブクラスExemptもしくはContractorに含まれるものすべて

    View Slide

  64. 64
    select p from Person p
    where 'Joe’ member of p.nicknames
    JPQLの書き方-コレクションに含まれている場合
    Collectionに含まれるものの検索
    Personは複数のnicknameを持ち
    その中に’Joe’が含まれているものを返す

    View Slide

  65. 65
    select new dev.megascus.CustomerDetail(c.id, c.name,
    c.department.name) from Customer c
    JPQLの書き方-コンストラクタ式
    コンストラクタに引数を渡す形でJavaオブジェクトを直接生成できる

    View Slide

  66. 66
    ABS, ALL, AND, ANY, AS, ASC, AVG, BETWEEN, BIT_LENGTH, BOTH, BY, CASE, CEILING,
    CHAR_LENGTH, CHARACTER_LENGTH, CLASS, COALESCE, CONCAT, COUNT, CURRENT_DATE,
    CURRENT_TIME, CURRENT_TIMESTAMP, DELETE, DESC, DISTINCT, ELSE, EMPTY, END, ENTRY,
    ESCAPE, EXISTS, EXP, EXTRACT, FALSE, FETCH, FLOOR, FROM, FUNCTION, GROUP, HAVING,
    IN, INDEX, INNER, IS, JOIN, KEY, LEADING, LEFT, LENGTH, LIKE, LOCAL, LN, LOCATE, LOWER,
    MAX, MEMBER, MIN, MOD, NEW, NOT, NULL, NULLIF, OBJECT, OF, ON, OR, ORDER, OUTER,
    POSITION, POWER, ROUND, SELECT, SET, SIGN, SIZE, SOME, SQRT, SUBSTRING, SUM, THEN,
    TRAILING, TREAT, TRIM, TRUE, TYPE, UNKNOWN, UPDATE, UPPER, VALUE, WHEN, WHERE
    ※そのほかSQLで使うキーワードは将来予約語になる可能性があるため使用は推奨されない
    JPQLの予約語(=使える機能)

    View Slide

  67. 67
    ▸ JavaとSQLで実行時の差異がある場合はSQLでの取り扱いを期待して書く必要がある
    ・ Nullの比較
    ・ 文字列比較
    ・ 暗黙の型変換
    ・ など・・・
    (注意)JPQLはSQLに変換されて実行される

    View Slide

  68. 68
    EntityManagerのメソッドから実行できる
    ▸ Selectの例
    em.createQuery(“SELECT c FROM Customer c WHERE c.name LIKE :custName”)
    .setParameter(“custName”, “Scott”) // custNameに”Scott”をバインド
    .setMaxResults(10) // 結果を10件に絞る
    .getResultList(); // 結果をListとして取得
    ※結果を1件のみ取得するメソッドも存在する
    ※update、deleteはJDBCと同じように別のメソッドが準備されている
    JPQLの実行方法

    View Slide

  69. 69
    ▸ JPA用のSQLライクなクエリー言語が存在する
    ▸ SQLにはないJPQL特有の書き方が存在する
    ▸ エンティティに対してクエリーを書くが、実際にはSQLに変換されて実行される
    ▸ クエリーはEntityManagerのメソッドから実行できる
    ここまでのまとめ

    View Slide

  70. その他の話題(7/7)
    70

    View Slide

  71. 71
    ▸ SQLを直接実行することもできる
    ▸ この場合永続化コンテキストは経由しない
    SQLの実行(ネイティブクエリー)

    View Slide

  72. 72
    ▸ JPAのライブラリはエンティティからテーブルを生成することができる
    ・ 開発時にどういうテーブルにマッピングしようとしているかを確かめることができる
    ▸ 本番環境でもポータブルなアプリケーションを作成したい場合は便利
    エンティティからテーブルの生成

    View Slide

  73. 73
    ▸ IDEを含むいくつかのOSSがテーブルからJPAエンティティを生成する事をサポートしている
    ▸ すでに既存のデータベースがある場合は一からエンティティを書くのではなく、こういったツールの
    使用を検討する
    ▸ 外部キーが設定されていない場合はエンティティ間の関連が自動で作られないので注意
    テーブルからエンティティの生成

    View Slide

  74. 74
    Jakarta EEを始めるなら
    Eclipse Starter for Jakarta EE

    View Slide

  75. 75
    https://eclipse-ee4j.github.io/jakartaee-tutorial/
    Jakarta EEのチュートリアル。(英語なのでGoogle翻訳とかで翻訳しつつ)
    The Jakarta® EE Tutorial

    View Slide

  76. linkedin.com/company/red-hat
    youtube.com/user/RedHatVideos
    facebook.com/redhatinc
    twitter.com/RedHat
    76
    Red Hat is the world’s leading provider of
    enterprise open source software solutions. Award-
    winning support, training, and consulting services
    make
    Red Hat a trusted adviser to the Fortune 500.
    Thank you

    View Slide

  77. 77
    JJUG CCC 2023 Spring 6月4日開催!

    View Slide