SlideShare a Scribd company logo
1 of 116
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
やさしく理解するはじめてのJPA
JPAの使い方
川場 隆
活水女子大学
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 3
・「わかりやすい」Javaの本をいくつか書きました。
・昨年11月に出した「わかりやすいJavaEE」は、大学生など、Java初心者向けに書いた入門書です。
・最初から<金魚本>では辛い 「わかりやすいJavaEE」をまず読むと、理解が進みます。
2014.11 2015.03
今日は、「わかりやすいJavaEE」の15~18章
(JPA)を要約して、お話します。
川場隆/http://k-webs.jp
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
内容
JPAの仕組み
いろいろなエンティティマッピング
オブジェクト関係マッピング
操作の主役はJPQL
1
2
3
4
4
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
内容
JPAの仕組み
いろいろなエンティティマッピング
オブジェクト関係マッピング
操作の主役はJPQL
1
5
2
3
4
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
1. JPA(Java persistent API)の役割と効果
6
オブジェクトの世界 データベース(RDB)の世界JPA
キーカラムで関連するテーブルを結合する
INFORMATION テーブルのキー
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
1. JPA(Java persistent API)の役割と効果
7
オブジェクトの世界 データベース(RDB)の世界JPA
参照でオブジェクトを関連付ける
Informationオブジェクトの参照
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
1. JPA(Java persistent API)の役割と効果
8
オブジェクトの世界 データベース(RDB)の世界JPA
・変換指定(マッピング)はアノテーションだけでOK
・Javaオブジェクトをそのまま、読み・書き・削除・検索などできる
・オブジェクト指向の問い合わせ言語(JPQL)が使える
・JPQLと同等なAPIも使える
JavaオブジェクトとRDB(レコード、テーブル)との自動変換
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 9
2. すべての操作を行うEntityManger
エンティティマネージャーを使ってデータベース処理を実行する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 10
2. すべての操作を行うEntityManger
エンティティマネージャーを使ってデータベース処理を実行する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 11
2. すべての操作を行うEntityManger
エンティティマネージャーを使ってデータベース処理を実行する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 12
3. エンティティの作成(基本)
エンティティ=データベースに保管するオブジェクト
エンティティクラスの要件
① クラスに@Entityを付ける
② 主キーの項目に@idを付ける
③ publicで引数のないコンストラクタを持つ
④ カプセル化する
⑤ final修飾子をクラスやフィールドに使わない
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 13
3. エンティティの作成(基本)
import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
public class Employee implements Serializable {
@Id @NotNull
private Integer number; // 社員番号
private String name; // 氏名
private String mail; // メール
public Employee(){}
public Employee(Integer number, String name, String mail){
・・・ ・・・
}
// セッター、ゲッター(省略)
}
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 14
3. エンティティの作成(基本)
import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
public class Employee implements Serializable {
@Id @NotNull
private Integer number; // 社員番号
private String name; // 氏名
private String mail; // メール
public Employee(){}
public Employee(Integer number, String name, String mail){
・・・ ・・・
}
// セッター、ゲッター(省略)
}
ビーンバリデーションも指定できる
@NotNull ---- Null禁止
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 15
3. エンティティの作成(基本)
import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
public class Employee implements Serializable {
@Id @NotNull
private Integer number; // 社員番号
private String name; // 氏名
private String mail; // メール
public Employee(){}
public Employee(Integer number, String name, String mail){
・・・ ・・・
}
// セッター、ゲッター(省略)
}
実用上は、
インスタンスを作成するためのコンストラク
タも作っておく
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 16
3. エンティティの作成(基本)
import java.io.Serializable;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
public class Employee implements Serializable {
@Id @NotNull
private Integer number; // 社員番号
private String name; // 氏名
private String mail; // メール
public Employee(){}
public Employee(Integer number, String name, String mail){
・・・ ・・・
}
// セッター、ゲッター(省略)
}
Netbeansで自動生成
① エディタ上で右ボタン
②[コードを挿入]を選択
③[取得メソッドおよび設定メソッド]を選択
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 17
4. EntityManger の機能
エンティティマネージャーを使ってデータベース処理を実行する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 18
4. EntityManagerの機能
メソッド 機 能
void persist(Object e ) エンティティeをデータベースに新規登録する
E merge( E e) データベースの中のエンティティを引数のエンティティeで更新する
void remove(Object e) エンティティeを(データベースから)削除する
E find(E.class, Object key) key(主キー)で検索して発見したエンティティを返す
E getReference(E.class, Object key) findと同様だが遅延フェッチする
void refresh(Object e) 永続性コンテキストにあるエンティティeをデータベースから取得した値で更新
void clear() 永続性コンテキストをクリアし、エンティティを永続性コンテキストから分離
void flush() 永続性コンテキストにあるエンティティを即時にデータベースと同期する
void detach(Object e) 引数のエンティティを、永続性コンテキストから分離する
boolean contains(Object e) 引数に指定したエンティティが永続性コンテキストの中にあるかどうか調べる
javax.persistence パッケージ
interface EntityManager
※Eはエンティティの型を表し、Class<E>をE.classと表記しています。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 19
@stateless
public class Db {
@PersistenceContext
private EntityManager em;
public void create(Employee obj){
em.persist(obj); // 挿入
}
public void update(Employee obj){
em.merge(obj); // 更新
}
・・・・・・・・
}
EJBのクラスで使用する
トランザクション管理を
EJBコンテナがやってくれ
るので、単に永続性コン
テキストを相手にして、
読み書き、検索を行えば
よい。
commit、rollback、などは
EJBコンテナが自動的に行
う。
エンティティマネージャーはDIで取得する
4. EntityManagerの機能<使い方>
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 20
6. CRUDのための汎用クラス
@stateless
public class Db {
@PersistenceContext
private EntityManager em;
public void create(Employee obj){
em.persist(obj);
}
public void update(Employee obj){
em.merge(obj);
}
・・・・・・・・
}
エンティティごとにこのような
EJBが必要なので、いくつもの
エンティティを使う時、とても
面倒。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 21
6. CRUDのための汎用クラス
public class Db<T> {
@PersistenceContext
private EntityManager em;
public void create(T obj) {
em.persist(obj);
}
public void update(T obj) {
em.merge(obj);
}
・・・・・・・・
}
どんな型のエンティティでも処
理できるように、総称型のスー
パークラスを使っておく。
@stateless
public class EmployeeDb extends Db<Employee>{
}
エンティティごとにこれだ
け書けばよい。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 22
6. CRUDのための汎用クラス
public class Db<T> {
private Class<T> cl; //型情報
@PersistenceContext
private EntityManager em;
public Db(Class<T> cl){
this.cl = cl;
}
public void create(T obj) {
em.persist(obj);
}
public T find(Object id) {
return em.find(cl, id);
}
・・・・・・・・
}
検索系のメソッドでは、エン
ティティの型情報も必要なので、
コンストラクタで受け取るよう
に修正。
クラス型
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 23
例えば、EmployeeDb ← Employeeエンティティの処理クラス
6. CRUDのための汎用クラス
@stateless
public class EmployeeDb extends Db{
public EmployeeDb(){
super(Employee.class);
}
}
結局、エンティティごと
にこれだけ書けばよい。
@EJB
EmployeeDb db;
・・・
メソッドの中で
Employee e = new Employee(・・・)
db.create(e);
このように使う
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 24
6. CRUDのための汎用クラス
メソッド名 機 能
public void create(T entity) 新規登録する
public void edit(T entity) 更新する
public void delete(T entity) 削除する
public T find(Object id) キーによる検索
public List<T> findAll() 全件を取得する
public List<T> findRange(int[] range)
range[0]からrange[1]の範囲のエンティ
ティを取得
public int count() 全件数を返す
※ http://k-webs.jp/JavaEE/ からダウンロードできます
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 25
7. エンティティのライフサイクル
エンティティマネージャーを使ってデータベース処理を実行する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 26
7. エンティティのライフサイクル
永続性コンテキスト
管理状態 管理状態
管理状態 管理状態
RDB
削除状態
分離状態
persist() merge()
find()
remove()
detach()
clear()
RDBとの同期
・トランザクション終了時
・クエリ発行時
・flash()メソッド実行時
・reload()メソッド実行時
デフォルトでエンティティ
をキャッシュする。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 27
メソッド 本来の意味
persist 新しくエンティティを管理対象にする
merge detachしたエンティティなど対象外のエンティティを再度管理対象とする
remove エンティティを削除対象にする
find IDによってエンティティを検索し管理対象にする
detach 引数で指定されたエンティティを管理対象外(分離)にする
clear 全てのエンティティを管理対象外にする
6. エンティティのライフサイクル
★ メソッドは「対象にする」だけで、RDBとの同期はエンティティマネージャーが管理している
@stateless
public class Db {
@PersistenceContext
private EntityManager em;
public void save(Employee obj){
em.persist(obj);
obj.setName(“鈴木”);
}
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 28
7. 永続性ユニットとデータベース接続
<データベースサーバー>
① データベースを作成する(ex. mydb)
<アプリケーションサーバー>
② RDBのJDBCのドライバを置く
③ コネクションプールとデータソース
を登録する
<アプリケーション>
④ データベース接続情報を作成する
(永続性ユニット=persistence.xml)
事前に1回だけ
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 29
7. 永続性ユニットとデータベース接続
<データベースサーバー>
① データベースを作成する(ex. mydb)
<アプリケーションサーバー>
② RDBのJDBCのドライバを置く
③ コネクションプールとデータソース
を登録する
<アプリケーション>
④ データベース接続情報を作成する
(永続性ユニット=persistence.xml)
アプリケーション毎に
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 30
7. 永続性ユニットとデータベース接続
アプリケーション
は永続性ユニット
の情報により、
データベースにア
クセスする。
複数の永続性
ユニットを作って、
複数のデータ
ベースをハンドリ
ンクできる。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 31
7. 永続性ユニットとデータベース接続(JavaEE)
IDEは、永続性ユニット(persistence.xml)を自動生成
する機能がある。
NetBeansでは、サーバーにコネクションプールやデー
タソースが作成されていない場合、その作成処理も
合わせて行うことができる。
右の動画で、MySQLをインストール直後、ee7 という
名前のデータベースを作成し、アプリケーションで使
用できるようにする設定手順を示す。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 32
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
db.create(emp);
return null;
}
// セッター、ゲッター
}
8. JPAの使い方 (EE)
JavaEE で、ウェブ画面で入力したデータ
を受け取ってデータベースに書き込む処理
を説明する。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 33
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
db.create(emp);
return null;
}
// セッター、ゲッター
}
8. JPAの使い方 (EE)
フィールドの各項目は、プログラムの変数
に バインド(結合)されている。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 34
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
db.create(emp);
return null;
}
// セッター、ゲッター
}
8. JPAの使い方 (EE)
このようなウェブは JSF で作成し、データ
を受け取るプログラムをバッキングビーン
という。
バッキングビーン
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 35
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
db.create(emp);
return null;
}
// セッター、ゲッター
}
8. JPAの使い方 (EE)
JSFでは、ボタンを押したとき起動するメ
ソッドを指定できる。例では、登録ボタン
を押すと create メソッドが起動する。
バッキングビーン
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 36
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
db.create(emp);
return null;
}
// セッター、ゲッター
}
8. JPAの使い方 (EE) バッキングビーン
create メソッドは、ウェブから受け取った
データで、Employeeエンティティ(オブ
ジェクト)を作成し、db.create でデータ
ベースに登録する。
db はEJB(Enterprise Java Beans)なのでDI
で取得する。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
db.create(emp);
return null;
}
// セッター、ゲッター
}
@Stateless
public class EmployeeDb {
@PersistenceContext
private EntityManager em;
public void create(Employee emp) {
em.persist(emp);
}
}
37
8. JPAの使い方 (EE)
DI でエンティティマ
ネージャを取得する
データベースに登録する
データベース処理は EJB に書く。
EJBコンテナがデータベースのトランザク
ション処理を管理してくれるので、記述
が簡単になる。
begin, commit, close, rollback など不要。
バッキングビーン
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@Named
@RequestScoped
public class Bb {
private Integer number;
private String name;
private String mail;
@EJB
EmployeeDb db;
public String create() {
Employee emp =
new Employee(number, name, mail);
try {
db.create(emp);
}catch(Exception e){
// 例外処理
}
return null;
}
// セッター、ゲッター
}
38
8. JPAの使い方 (EE) バッキングビーン
新規データの書き込みで、すでに同じ
キーを持つデータが存在している場合な
どは例外が発生する。例外処理が必要な
場合は、try-catch の中でEJBのメソッドを
呼び出す。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
内容
JPAの仕組み
いろいろなエンティティマッピング
オブジェクト関係マッピング
操作の主役はJPQL
1
39
2
3
4
※ 動かせる例題プロジェクトを http://k-webs.jp/JavaEE/ からダウンロードできます
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 40
① エンティティのクラス名をテーブル名とする
② フィールド変数名をテーブルのカラム名とする
③ データ型はRDBの種類で若干異なる名前になる
1. デフォルトのマッピング (設定より規約)
@Entity
public class Employee {
@id
private Integer number;
private String name;
・・・
}
[PK] NUMBER NAME
EMPLOYEE テーブル
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 41
1. デフォルトのマッピング (設定より規約)
アノテーションによりデフォルトのマッピングを変更できる
1. テーブルの構成 を指定するアノテーション
2. 主キーの構成 を指定するアノテーション
3. フィールド に個別の属性を指定するアノテーション
4. その他のアノテーション
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 42
2. テーブルの構成を指定するアノテーション
1 @Table RDBのテーブル名を指定する
2 @Secondarys
@Secondary
@Column
エンティティを複数のRDBテーブルに分割する
3 @Embeddable
@Embedded
複数のクラスからひとつのエンティティを構成
する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 43
2. テーブルの構成を指定するアノテーション
1 @Table RDBのテーブル名を指定する
2 @Secondarys
@Secondary
@Column
エンティティを複数のRDBテーブルに分割する
3 @Embeddable
@Embedded
複数のクラスからひとつのエンティティを構成
する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 44
2. テーブルの構成を指定するアノテーション
1 @Table RDBのテーブル名を指定する
2 @Secondarys
@Secondary
@Column
エンティティを複数のRDBテーブルに分割する
3 @Embeddable
@Embedded
複数のクラスからひとつのエンティティを構成
する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 45
2-1. RDBのテーブル名を指定する
@Entity
@Table(name = "EMP_TBL")
public class Employee implements Serializable {
@Id @NotNull
private String id;
private String eval;
private String name;
・・・
}
@Table により、RDBの
テーブル名を指定する。
テーブル名は
EMPLOYEE ではなく
EMP_TBL になる
積極的に使用する。
SQLの予約語と衝突
しないよう、末尾
に_TBLなどを付け
るのがよい。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 46
2-2. エンティティを複数のテーブルに分ける
@Entity
@SecondaryTables({
@SecondaryTable(name = "ADDRESS"),
@SecondaryTable(name = "SKILL")
})
public class Employee1 implements Serializable {
@Id
private String id;
@Column(table = "ADDRESS")
private String city;
@Column(table = "SKILL")
private String eval;
private String name;
・・・
}
@Columnを使って、
city を ADDRESS テーブ
ルに、eval を SKILL テー
ブルに割り当てる。
分割先のテーブル名を
指定する。
@SecondaryTableを複数
指定できる
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 47
2-2. エンティティを複数のテーブルに分ける
@Entity
@SecondaryTables({
@SecondaryTable(name = "ADDRESS"),
@SecondaryTable(name = "SKILL")
})
public class Employee1 implements Serializable {
@Id
private String id;
@Column(table = "ADDRESS")
private String city;
@Column(table = "SKILL")
private String eval;
private String name;
・・・
}
EMPLOYEE1
ADDRESS
SKILL
3つのテーブルが
できる
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 48
2-3. 複数のクラスからエンティティを構成する
@Entity
public class Employee2 implements Serializable {
@Id
private Long id;
private String name;
@Embedded
private Tel tel;
・・・
}
@Embeddable
public class Tel implements Serializable {
private String telephone;
private String cellular;
・・・
}
@Embeddedで、
フィールドに合成する
他のクラスを指定する。
@Embeddedは複数指
定できる。
エンティティの一部に
なるクラスには、
@Embeddable
を付ける
String telephone;
String cellular;
※ 2項目に展開される
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 49
3. 主キーを指定するアノテーション
1 @Id
@GeneratedValue 主キーの自動生成を指定する
2 @Embeddable
@EmbeddedId
@Embeddableを付けたクラスのオブジェクトを
主キーにする。
3 @IdClass
@Id
@IdClassを付けたクラスのオブジェクトを主
キーにする。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 50
3. 主キーを指定するアノテーション
1 @Id
@GeneratedValue 主キーの自動生成を指定する
2 @Embeddable
@EmbeddedId
@Embeddableを付けたクラスのオブジェクトを
主キーにする。
3 @IdClass
@Id
@IdClassを付けたクラスのオブジェクトを主
キーにする。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 51
3. 主キーを指定するアノテーション
1 @Id
@GeneratedValue 主キーの自動生成を指定する
2 @Embeddable
@EmbeddedId
@Embeddableを付けたクラスのオブジェクトを
主キーにする。
3 @IdClass
@Id
@IdClassを付けたクラスのオブジェクトを主
キーにする。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 52
3. 主キーを指定するアノテーション
1 @Id
@GeneratedValue 主キーの自動生成を指定する
2 @Embeddable
@EmbeddedId
@Embeddableを付けたクラスのオブジェクトを
主キーにする。
3 @IdClass
@Id
@IdClassを付けたクラスのオブジェクトを主
キーにする。
※ 2と3は、エンティティで主キーに指定する方法が違うだけで、実質は同じ。
2の方法が簡単でよい。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 53
3-1. 主キーの自動生成を指定する
@Entity
public class Employee3 implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id ;
private String name;
・・・
}
主キーの生成方法を、
@GeneratedValueで指定。
GenerationType.AUTO 使用しているデータベースシステムの既定の方法を使う
GenerationType.TABLE SQLシーケンス名と現在値を格納したテーブルを使って自動生成する
GenerationType.SEQUENCE データベースのSQLシーケンスを使って自動生成する
GenerationType.IDENTITY データベースのIDカラムの値を主キーの値とする
普通はAUTOを指定する
主キーを自動生成
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 54
3-2. 別のクラスのオブジェクトを主キーにする
主キーにするクラスに
@Embeddableを付ける
@Entity
public class Employee4 implements Serializable {
@EmbeddedId
private CompositeKey id; // 主キー
private String name;
・・・
}
@EmbeddedIdでクラス
オブジェクトを主キー
に指定する
@Embeddable
public class CompositeKey implements Serializable {
private String groupId;
private String userId;
・・・
}
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 55
3-3. 別のクラスのオブジェクトを主キーにする
public class CompositeKey implements Serializable {
private String groupId;
private String userId;
・・・
}
主キーにするクラスは
アノテーション不要
@Entity
@IdClass(CompositeKey.class)
public class Employee5 implements Serializable {
@Id
private String groupId;
@Id
private String userId;
private String name;
@Idで主キー項目を指定
全てのフィールドを同
じ名前でもれなく指定
すること。
@IdClassで主キーにする
クラスを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 56
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値の記録形式を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 57
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値の記録形式を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 58
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値の記録形式を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 59
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値の記録形式を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 60
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値の記録形式を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 61
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値の記録形式を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 62
4.フィールド に個別の属性を指定するアノテーション
1 @column フィールドに対応するテーブルカラムを指定する
2 @Basic
@Lob
遅延フェッチを指定できる
ファイルなど大きいデータであることを示す
3 @Enumerated 列挙を名前と序数のどちらで記録するか指定
4 @TemporalType Date, Calendar型の値のデータベース型を指定
5 @ElementCollection
@CollectionTable
@MapKeyColumn
@Column
基本型のList, Set, MapをRDBに割り付ける
割り付け先のテーブル名を指定する
割り付け先テーブルでのキーカラム名を指定
割り付け先テーブルでのカラム名を指定
6 @Transient データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 63
@Entity
public class Employee implements Serializable {
@Id
@Column(name = “E_ID", nullable = false, length=50)
private Integer id;
@Column(name=“E_VALUE", updatable=false, precision=12, scale=2)
public BigDecimal val;
・・・
}
テーブルのカラム名 null にできない 長さは50文字
値を更新できない 12桁の精度 整数部2桁
4-1. @Column
フィールドの属性を指定する。
テーブルを生成する際に適用される。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 64
@Entity
public class Employee implements Serializable {
@Lob
@Basic(fetch=LAZY)
private byte[] picture;
・・・
@Lob
@Basic(fetch=EAGER)
protected String report;
@Basic(Optional=false)
private Book book;
}
ラージオブジェクト
4-2. @Lob @Basic
遅延フェッチする(レコード読出し時には空で、
実際に、フィールドの値が使われる時、値を取り出す。
nullを入れることができない
即座にフェッチする(既定値)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 65
public enum GroupColor {GREEN, BLUE, RED}
public enum Employee_Status {FULL_TIME, PART_TIME, CONTRACT}
@Entity
public class Employee implements Serializable {
@Enumerated(ODINAL)
private GroupColor color;
@Enumerated(String)
private Employee_Status status;
}
4-3. @Enumerated
列挙を数値で記録する(既定値)
文字列で記憶すると、列挙の内容を変更しても安全。
列挙を文字列で記録する
列挙型
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 66
@Entity
public class Employee implements Serializable {
@Temporal(TIMESTAMP)
private Date dateTime;
@Temporal(TIME)
private Date startTime;
@Temporal(DATE)
private Calendar birthday;
}
4-4. @Temporal
年月日 時分秒
時分秒
年月日
java.util.Date と java.util.Calendar には必ず指定しなければならない。
指定を忘れると、例外を発
生して、デプロイできなく
なります。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 67
@Entity
public class Employee implements Serializable {
@Id
private Long id;
private String name;
@ElementCollection
private List<String> notes;
@ElementCollection
private Map<Integer, String> items;
}
4-5. @ElementCollection
List
@ElementCollectionで、Collection、List、Set、Mapをデータベースに割り付ける
フィールド
・Collection List Set
・Map
ただし、要素は、Stringや
基本データ型のラッパーク
ラスに限る。
Map
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
4-5. @ElementCollection
EMPLOYEE
ID NAME
100 田中
200 鈴木
EMPLOYEE_NOTES
EMPLOYEE_ID NOTES
100 A商店
100 B商店
200 C商店
EMPLOYEE_ITEMS
EMPLOYEE_ID ITEMS ITEMS_KEY
100 ビール 1
100 ウィスキー 2
200 ビール 1
200 焼酎 3
@Id
private Long id;
private String name;
@ElementCollection
private List<String> notes;
@ElementCollection
private Map<Integer, String> items;
テーブル名、カラム名
は規約により決定。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
4-5. @ElementCollection
テーブル名、カラム名を変更するには他のアノテーションを追加する
@CollectionTable
@Column
@MapKeyColumn
割り付け先のテーブル名を指定する
割り付け先テーブルでのカラム名を指定
割り付け先テーブルでのキーカラム名を指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
4-5. @ElementCollection NOTE_TBL
EMPLOYEE_ID MEMO
100 A商店
100 B商店
200 C商店
ITEM_TBL
EMPLOYEE_ID NAME NUMBER
100 ビール 1
100 ウィスキー 2
200 ビール 1
200 焼酎 3
@Id
private Long id;
private String name;
@ElementCollection
@CollectionTable(name="NOTE_TBL")
@Column(name="MEMO")
private List<String> notes;
@ElementCollection
@CollectionTable(name="ITEM_TBL")
@Column (name="NAME")
@MapKeyColumn (name="NUMBER")
private Map<Integer, String> items;
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 71
@Entity
public class Employee implements Serializable {
@Transient
private int flag;
}
※シリアライズしない変数につける transient 修飾子と似ている
4-6. @Transient
データベースに保存しないフィールドを指定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
内容
JPAの仕組み
いろいろなエンティティマッピング
オブジェクト関係マッピング
操作の主役はJPQL
1
72
2
3
4
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
5つのパターン
① One-to-One
② One-to-Many
③ One-to-One(双方向)
④ One-to-Many、Many-to-One (双方向)
⑤ Many-to-Many (双方向)
73
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 74
1. One-to-One (1対1の関係)
顧客(ID、名前、顧客情報) 顧客情報(ID、住所、電話、携帯)
必ず1対1に対応する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 75
1. One-to-One (1対1の関係)
 エンティティの定義
@Entity
public class Customer
implements Serializable {
@Id
private String customerId;
private String name;
private Information info;
・・・・・
@Entity
public class Information
implements Serializable {
@Id
@GeneratedValue(strategy
=GenerationType.AUTO)
private Long id;
private String address;
private String phone;
private String cellular;
・・・・・顧客情報オブジェクト
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 76
@EJB
InformationDb infoDb;
@EJB
CustomerDb cusDb;
・・・・・・
public void write(){
}
データベースに保存処理
1. One-to-One (1対1の関係)
 永続化(データベース)処理
汎用CRUDクラスから作成したそれぞれの
エンティティ用のEJBをDIで取得しておく
具体的な処理はここに書く
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 77
Information info1
= new Information("東京都", "03-333-3333", "090-333-3333");
Customer c1
= new Customer("cus001", "田中宏", info1);
infoDb.create(info1);
cusDb.create(c1);
データベースに保存
1. One-to-One (1対1の関係)
 永続化(データベース)処理
それぞれをDBに保存
顧客情報も忘れずに
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 78
外部キー結合:外部キーで関連するテーブルを結合する
INFORMATION テーブルのキー
1. One-to-One (1対1の関係)
 RDBでの保存形式は次のようになる
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 79
Information info1
= new Information("東京都", "03-333-3333", "090-333-3333");
Customer c1
= new Customer("cus001", "田中宏", info1);
infoDb.create(info1);
cusDb.create(c1);
データベースに保存
1. One-to-One (1対1の関係)
 カスケード処理
どちらか1つだけ保存すればよいようにしたい
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 80
@Entity
public class Customer
implements Serializable {
@Id
private String customerId;
private String name;
@OneToOne(cascade = {CascadeType.ALL})
private Information info;
・・・・・
1. One-to-One (1対1の関係)
 カスケード処理
@Entity
public class Information
implements Serializable {
@Id
@GeneratedValue(strategy
=GenerationType.AUTO)
private Long id;
private String address;
private String phone;
private String cellular;
・・・・・
DB操作をする方にカスケードを指定する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 81
Information info1
= new Information("東京都", "03-333-3333", "090-333-3333");
Customer c1
= new Customer("cus001", "田中宏", info1);
cusDb.create(c1);
データベースに保存
1. One-to-One (1対1の関係)
 カスケード処理
これだけでOK!
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 82
カスケード指定 カスケードするイベント 対応するメソッド
CascadeType.PERSIST 新規保存 persist
CascadeType.MERGE 更新 merge
CascadeType.REMOVE 削除 remove
CascadeType.REFRESH 永続性コンテキストのエンティティをデータベー
スから再取得した値で更新 refresh
CascadeType.DETACH 永続性コンテキストからエンティティを分離する detach
CascadeType.ALL 上記のすべての操作
使用例: @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
1. One-to-One (1対1の関係)
 カスケード処理
ALL以外では、必要なものだけを指定できる
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
1. One-to-One (1対1の関係)
① DB操作を実行する方に、 @OneToOne(cascade={~})を付ける
【要点】
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
5つのパターン
① One-to-One
② One-to-Many
③ One-to-One(双方向)
④ One-to-Many、Many-to-One (双方向)
⑤ Many-to-Many (双方向)
84
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 85
2. One-to-Many (1対多の関係)
注文(ID、顧客、注文明細)
注文明細(ID、品名、数量、日付)
1つの注文に複数の注文明細が対応する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 86
2. One-to-Many (1対多の関係)
 エンティティの定義
@Entity
public class Cart
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long cartID;
private String customer;
private List<OrderLine> orderLines;
・・・・・
@Entity
public class OrderLine
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long orderLineId;
private String item;
private int quantity;
@Temporal(TemporalType.DATE)
private Date orderDate;
・・・・・
これでOKですが、さらにカスケードしたいので・・・
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 87
2. One-to-Many (1対多の関係)
 エンティティの定義
@Entity
public class Cart
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long cartID;
private String customer;
@OneToMany(cascade = {CascadeType.ALL})
private List<OrderLine> orderLines;
・・・・・
@Entity
public class OrderLine
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long orderLineId;
private String item;
private int quantity;
@Temporal(TemporalType.DATE)
private Date orderDate;
・・・・・
cascadeは、DB操作を実行する方に設定する
@OneToManyの中にカスケードを指定する
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
① DB操作を実行する方に、カスケード指定をする
@OneToMany(cascade={~})または @ManyToOne(cascade={~})
【要点】
2. One-to-Many (1対多の関係)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
5つのパターン
① One-to-One
② One-to-Many
③ One-to-One(双方向)
④ One-to-Many、Many-to-One (双方向)
⑤ Many-to-Many (双方向)
89
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 90
3. One-to-One (1対1の関係) + 双方向
顧客(ID、名前、顧客情報) 顧客情報(ID、住所、電話、携帯)
必ず1対1に対応するが、双方が互いの参照を持ち合う関係(双方向)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 91
1. One-to-One (1対1の関係) + 双方向
 エンティティの定義
@Entity
public class Customer
implements Serializable {
@Id
private String customerId;
private String name;
@OneToOne(cascade
= {CascadeType.ALL})
private Information info;
・・・・・
@Entity
public class Information
implements Serializable {
@Id
@GeneratedValue(strategy
=GenerationType.AUTO)
private Long id;
private String address;
private String phone;
private String cellular;
@OneToOne(mappedBy=“info”)
private Customer customer;
・・・・・
1方向の関係が2つにならないように、どちらかに mappedBy を指定する
関係の被所有者
関係の所有者
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
3. One-to-One (1対1の関係) + 双方向
【要点】
① DB操作を実行する方に、 @OneToOne(cascade={~})を付ける
② どちらか一方にだけ @OneToOne(mappedBy=~)を付ける
付けた方は<関係の被所有者>、相手方は<関係の所有者>
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
5つのパターン
① One-to-One
② One-to-Many
③ One-to-One(双方向)
④ One-to-Many、Many-to-One (双方向)
⑤ Many-to-Many (双方向)
93
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
注文(ID、顧客、注文明細) 注文明細(ID、品名、数量、日付)
94
4. One-to-Many と Many-to-One の 双方向
1つの注文に複数の注文明細が対応する。注文明細からもどの注文に属するかわかる(双方向)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@Entity
public class OrderLine
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long orderLineId;
private String item;
private int quantity;
@Temporal(TemporalType.DATE)
private Date orderDate;
private Cart cart;
・・・・・
95
 エンティティの定義
@Entity
public class Cart
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long cartID;
private String customer;
@OneToMany(mappedBy=“cart”,
cascade= {CascadeType.ALL})
private List<OrderLine> orderLines;
・・・・・
One-To-Many 側に mappedBy を付ける
関係の被所有者=One-to-Many側
関係の所有者=Many-to-One 側
4. One-to-Many と Many-to-One の 双方向
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
【要点】
① DB操作を実行する方に、 カスケード指定を付け る
② One-to-Many側に@OneToMany(mappedBy=~)を付ける
4. One-to-Many と Many-to-One の 双方向
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
5つのパターン
① One-to-One
② One-to-Many
③ One-to-One(双方向)
④ One-to-Many、Many-to-One (双方向)
⑤ Many-to-Many (双方向)
97
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 98
5. Many-to-Many 双方向 (1方向はない)
俳優=多くの映画に出演
(ID、顧客、映画のリスト)
映画=多くの俳優が出演
(ID、タイトル、出演俳優のリスト)
それぞれが、相手の多数と関係がある(多対多、双方向)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@Entity
public class Movie
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long id;
private String title;
private List<Actor> actors;
・・・・・
99
5. Many-to-Many 双方向 (1方向はない)
 エンティティの定義
@Entity
public class Actor
implements Serializable {
@Id
@GeneratedValue(strategy
= GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany(mappedBy="actors“)
private List<Movie> movies;
・・・・・
2つの1対多関係とならないように、どちらかに mappedBy を付ける(どちらでもよい)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
【要点】
① どちらかに @ManyToMany(mappedBy=“・・・”) を付ける
※エンティティの両方に、 カスケード指定、cascade={CascadeType.PERSIST} を付けないと
保存できないという問題がありました。
5. Many-to-Many 双方向 (1方向はない)
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
内容
JPAの仕組み
いろいろなエンティティマッピング
オブジェクト関係マッピング
操作の主役はJPQL
1
101
2
3
4
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 102
1. JPQL(Java Persistence Query Language)の位置付け
問い合わせの方法 特 徴
JPQL
SQLと似ている
どのDB製品でも共通の命令を使える
オブジェクト指向(Javaの変数名、自動的なJOIN)
Native Query SQLをそのまま適用
Criteria API
JPQLと同等の問い合わせをプログラムできる
動的にクエリを組み立てることができる
型チェックが働くので間違いが減る
記述は面倒
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
注文(ID、顧客、注文明細)
注文明細(ID、品名、数量、日付)
103
この章で対象とするエンティティ(One-to-Many 双方向)
1. JPQL(Java Persistence Query Language)の位置付け
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 104
2. JPQLの文法 (1/5)
select c from Cart c
select c from Cart c where c.name = ‘田中’
・クエリの基本形
・c はエンティティの別名(エイリアス)
・select 句にエイリアスを指定すると、全件を取得する意味になる
・where句などでは、エイリアスのプロパティ(フィールド名)を使って記述する
演算子 備 考
= c.name=’山田'
>, >= c.price>1000
<, <= c.price<=500
<> c.price <> 1000
BETWEEN c.price BETWEEN 100 and 1000
演算子 備 考
LIKE 文字列の一致を検査する
IN ()内のリストに該当があるか
IS NULL
IS EMPTY
AND OR NOT ()
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 105
2. JPQLの文法 (2/5)
select o from OrderLine o where o.cart.customer = '田中宏'
関係のあるエンティティでは自動的にJOINが働く
本来なら、join を使って次のように書くところ。
select o from OrderLine o join Cart c on o.cart.cartID = c.cartID
where o.cart.customer = '田中宏'
select count(c) from Cart c where c.customer = ‘田中’
select o.item, max(o.quantity) from OrderLine o
集計関数も使える
全ての関数は次のURLにマニュアルがある
https://docs.oracle.com/javaee/7/tutorial/persistence-querylanguage005.htm#BNBVP
Customerの値は Cartテーブルから取り出している
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 106
2. JPQLの文法 (3/5)
Object[] array = select c.customer, count(c) from OrderLine o
join Cart c on o.cart = c group by c
・エンティティ以外の結果は、Object[] 型になり、キャストが必要で記述が面倒
顧客ごとの、顧客名と注文の件数を得る
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 107
2. JPQLの文法 (3/5)
List<Sum> ls = select new beans.Sum(c.customer, count(c)) from OrderLine o
join Cart c on o.cart = c group by c
・エンティティ以外の結果は、Object[] 型になり、キャストが必要で記述が面倒
・結果をマップするクラスを作成しておいて、そのオブジェクトに受け取ると便利
package bean;
public class Sum{
private String name;
private long count;
public Sum(String name, long count){
this.name = name;
this.count = count;
}
// セッター、ゲッター等
}
エンティティでなく、普通の
クラスでよい。
List<Sum> で結果を受け取
れる。
コンストラクタで受ける
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 108
2. JPQLの文法 (4/5)
select distinct c from Cart c join fetch c.orderLines
CartとそのOrderLine(複数)を一度に取得するSQLを生成する
One-to-Manyの関係でのN+1問題(=Cartから全データを取得すると、CartエンティごとにOrderlineエン
ティを取得するSQLが生成される)に対応する書き方
select c from Cart c
select distinct c from Cart c join fetch c.orderLines
Cartを取得 Cartが持つ OrderLine を取得
SQL がひとつだけになった
One-to-Many は 遅延フェッチ(LAZY) がデフォルト
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 109
★JPQL実行時に、実行されたSQLログを取る設定
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 110
2. JPQLの文法 (5/5)
update OrderLine o set o. quantity = 10 where o.cart.customer = ‘田中宏’
エンティティの一括更新
delete from OrderLine o where o. orderDate = ‘2019-01-04’
エンティティの一括削除
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 111
3. JPQLの実行方法
JPQLの実行方法の種類
動的クエリ JPQLをそのまま実行する (簡単だが効率はよくない)
名前付きクエリ
エンティティの中にJPQLを作成して名前を付けておき
その名前を使って実行する
@Stateless
public class MyDbOperation{
@PersistenceContext
private EntityManager em;
List<Cart> getCartAll(){
}
・・・・・・
}
JPQLを実行(ここではCartの全件検索処理)
EJBのクラスを作成して、
その中でJPQLを実行する。
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@NamedQueries ({
@NamedQuery(name= OrderLine.ALL,
query="select o from OrderLine o where o.item= :itemName"),
@NamedQuery(name=OrderLine.ALL_DESC,
query="select o FROM OrderLine o order by o.quantity desc")
})
@Entity
@Table(name = "ORDERLINE_TBL")
public class OrderLine implements Serializable {
public static final String ALL = "ALL";
public static final String ALL_DESC = "ALL_DESC";
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long orderLineId;
・・・・・・
112
4. 名前付きクエリの作成
ソート指定 。
desc(降順)、asc(昇順)
asc が既定値
名前をエンティティクラスのstatic変数にしておく。
EJBのプログラムで名前を書き間違うと、コンパイル
エラーになるので分かる。
パラメータ
値は実行時にセットできる
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@Stateless
public class MyDbOperation {
@PersistenceContext
private EntityManager em;
public List<OrderLine> orderLines(String item){
TypedQuery<OrderLine> q = em.createNamedQuery(OrderLine.ALL,OrderLine.class);
q.setParameter("itemName", item);
return q.getResultList();
}
・・・・・
}
113
5. EJBを作成(実行メソッドの作成)
"select o from OrderLine o where o.item= :itemName"
JPQL文字列 クラス型
return em.createNamedQuery(OrderLine.ALL,OrderLine.class)
.setParameter("itemName", "ビール")
.getResultList();
メソッドチェーン可能
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@Stateless
public class MyDbOperation {
@PersistenceContext
private EntityManager em;
public List<OrderLine> orderLines(String item, int s, int n){
return em.createNamedQuery(OrderLine.ALL,OrderLine.class)
.setParameter("itemName", "ビール")
.setFirstResult(s)
.setMaxResult(n)
.getResultList();
}
・・・・・
}
114
5. EJBを作成(実行メソッドの作成)
s件目から読み込む
最高n件だけ読み込む
ページ制御ができる
http://k-webs.jp:8080/pagination/
Copyright © 2015, Oracle and/or its affiliates. All rights reserved. |
@EJB
MyDbOperation dao;
・・・・・・
public List<OrderLine>
getOrderLine(){
return dao.orderLines("ビール");
}
115
6. 名前付きクエリを実行
バッキングビーンでは、EJBをDIで取得し、
クエリを実行して、ウェブに結果を表示
できる。
JavaEEで作成したサンプルプログラムを試せます。
http://k-webs.jp:8080/zakka-ya-san/faces/index.xhtml
はじめてのJPA

More Related Content

What's hot

Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Taku Miyakawa
 
Java仮想マシンの実装技術
Java仮想マシンの実装技術Java仮想マシンの実装技術
Java仮想マシンの実装技術Kiyokuni Kawachiya
 
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話JustSystems Corporation
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方Yoshiyasu SAEKI
 
Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Norito Agetsuma
 
Ingress on Azure Kubernetes Service
Ingress on Azure Kubernetes ServiceIngress on Azure Kubernetes Service
Ingress on Azure Kubernetes ServiceToru Makabe
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patternsnekop
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーションssuser070fa9
 
Json型の使い方
Json型の使い方Json型の使い方
Json型の使い方tsudaa
 
単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介AdvancedTechNight
 
Webアプリって奥が深いんです
Webアプリって奥が深いんですWebアプリって奥が深いんです
Webアプリって奥が深いんですabend_cve_9999_0001
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるMasatoshi Tada
 
JBoss AS 7 / EAP 6 modules and class loading
JBoss AS 7 / EAP 6 modules and class loadingJBoss AS 7 / EAP 6 modules and class loading
JBoss AS 7 / EAP 6 modules and class loadingnekop
 
第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考えるchonaso
 

What's hot (20)

Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
SpringBootTest入門
SpringBootTest入門SpringBootTest入門
SpringBootTest入門
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 
Metaspace
MetaspaceMetaspace
Metaspace
 
Java仮想マシンの実装技術
Java仮想マシンの実装技術Java仮想マシンの実装技術
Java仮想マシンの実装技術
 
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
 
Mavenの真実とウソ
Mavenの真実とウソMavenの真実とウソ
Mavenの真実とウソ
 
ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方
 
Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2Javaトラブルに備えよう #jjug_ccc #ccc_h2
Javaトラブルに備えよう #jjug_ccc #ccc_h2
 
Ingress on Azure Kubernetes Service
Ingress on Azure Kubernetes ServiceIngress on Azure Kubernetes Service
Ingress on Azure Kubernetes Service
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patterns
 
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web ServiceアプリケーションAngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
AngularとSpring Bootで作るSPA + RESTful Web Serviceアプリケーション
 
Json型の使い方
Json型の使い方Json型の使い方
Json型の使い方
 
単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介単なるキャッシュじゃないよ!?infinispanの紹介
単なるキャッシュじゃないよ!?infinispanの紹介
 
Webアプリって奥が深いんです
Webアプリって奥が深いんですWebアプリって奥が深いんです
Webアプリって奥が深いんです
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
とにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みるとにかく分かりづらいTwelve-Factor Appの解説を試みる
とにかく分かりづらいTwelve-Factor Appの解説を試みる
 
JBoss AS 7 / EAP 6 modules and class loading
JBoss AS 7 / EAP 6 modules and class loadingJBoss AS 7 / EAP 6 modules and class loading
JBoss AS 7 / EAP 6 modules and class loading
 
AWS Lambdaを紐解く
AWS Lambdaを紐解くAWS Lambdaを紐解く
AWS Lambdaを紐解く
 
第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える第六回渋谷Java Java8のJVM監視を考える
第六回渋谷Java Java8のJVM監視を考える
 

Similar to はじめてのJPA

Beginning Java EE 6 勉強会(3) #bje_study
Beginning Java EE 6 勉強会(3) #bje_studyBeginning Java EE 6 勉強会(3) #bje_study
Beginning Java EE 6 勉強会(3) #bje_studyinatus
 
脱・独自改造! GebでWebDriverをもっとシンプルに
脱・独自改造! GebでWebDriverをもっとシンプルに脱・独自改造! GebでWebDriverをもっとシンプルに
脱・独自改造! GebでWebDriverをもっとシンプルにHiroko Tamagawa
 
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]David Buck
 
R5 3 type annotation
R5 3 type annotationR5 3 type annotation
R5 3 type annotationEIICHI KIMURA
 
WildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsWildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsYoshimasa Tanabe
 
Active Object
Active ObjectActive Object
Active Objecty-uti
 
Introduction to WildFly Swarm
Introduction to WildFly SwarmIntroduction to WildFly Swarm
Introduction to WildFly SwarmYoshimasa Tanabe
 
JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)
JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)
JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)NTT DATA Technology & Innovation
 
Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入
Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入
Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入Takayuki Konishi
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜JustSystems Corporation
 
商用ミドルウェアのPuppet化で気を付けたい5つのこと
商用ミドルウェアのPuppet化で気を付けたい5つのこと商用ミドルウェアのPuppet化で気を付けたい5つのこと
商用ミドルウェアのPuppet化で気を付けたい5つのことNTT DATA OSS Professional Services
 
Java ee6 with scala
Java ee6 with scalaJava ee6 with scala
Java ee6 with scalaSatoshi Kubo
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Yu Nobuoka
 
SDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireSDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireAkio Katayama
 
JPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発TipsJPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発Tipsyuichi_kuwahara
 
Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)Yuji Kubota
 
Spring2概論@第1回JSUG勉強会
Spring2概論@第1回JSUG勉強会Spring2概論@第1回JSUG勉強会
Spring2概論@第1回JSUG勉強会Mitsuhiro Okamoto
 
Java EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallJava EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallMasatoshi Tada
 

Similar to はじめてのJPA (20)

Beginning Java EE 6 勉強会(3) #bje_study
Beginning Java EE 6 勉強会(3) #bje_studyBeginning Java EE 6 勉強会(3) #bje_study
Beginning Java EE 6 勉強会(3) #bje_study
 
脱・独自改造! GebでWebDriverをもっとシンプルに
脱・独自改造! GebでWebDriverをもっとシンプルに脱・独自改造! GebでWebDriverをもっとシンプルに
脱・独自改造! GebでWebDriverをもっとシンプルに
 
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
 
R5 3 type annotation
R5 3 type annotationR5 3 type annotation
R5 3 type annotation
 
WildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsWildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE Apps
 
Active Object
Active ObjectActive Object
Active Object
 
Introduction to WildFly Swarm
Introduction to WildFly SwarmIntroduction to WildFly Swarm
Introduction to WildFly Swarm
 
JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)
JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)
JVMに裏から手を出す!JVMTIに触れてみよう(オープンソースカンファレンス2020 Online/Hiroshima 講演資料)
 
Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入
Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入
Javaone2012 BoF2-02 コンテナでテストをまわせ!Java EEへの自動テストの導入
 
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
 
商用ミドルウェアのPuppet化で気を付けたい5つのこと
商用ミドルウェアのPuppet化で気を付けたい5つのこと商用ミドルウェアのPuppet化で気を付けたい5つのこと
商用ミドルウェアのPuppet化で気を付けたい5つのこと
 
Java ee6 with scala
Java ee6 with scalaJava ee6 with scala
Java ee6 with scala
 
Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成Java による Web アプリケーションのプロトタイプのために最近使っている構成
Java による Web アプリケーションのプロトタイプのために最近使っている構成
 
SDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 WhireSDLoader SeasarCon 2009 Whire
SDLoader SeasarCon 2009 Whire
 
ぼく(たち)のかんがえた最新のJS開発環境 #scripty04
 ぼく(たち)のかんがえた最新のJS開発環境 #scripty04 ぼく(たち)のかんがえた最新のJS開発環境 #scripty04
ぼく(たち)のかんがえた最新のJS開発環境 #scripty04
 
JPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発TipsJPAの基礎と現場で役立つ開発Tips
JPAの基礎と現場で役立つ開発Tips
 
Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)Head toward Java 16 (Night Seminar Edition)
Head toward Java 16 (Night Seminar Edition)
 
Spring2概論@第1回JSUG勉強会
Spring2概論@第1回JSUG勉強会Spring2概論@第1回JSUG勉強会
Spring2概論@第1回JSUG勉強会
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
Java EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 FallJava EEハンズオン資料 JJUG CCC 2015 Fall
Java EEハンズオン資料 JJUG CCC 2015 Fall
 

はじめてのJPA

  • 1.
  • 2. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | やさしく理解するはじめてのJPA JPAの使い方 川場 隆 活水女子大学
  • 3. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 3 ・「わかりやすい」Javaの本をいくつか書きました。 ・昨年11月に出した「わかりやすいJavaEE」は、大学生など、Java初心者向けに書いた入門書です。 ・最初から<金魚本>では辛い 「わかりやすいJavaEE」をまず読むと、理解が進みます。 2014.11 2015.03 今日は、「わかりやすいJavaEE」の15~18章 (JPA)を要約して、お話します。 川場隆/http://k-webs.jp
  • 4. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 内容 JPAの仕組み いろいろなエンティティマッピング オブジェクト関係マッピング 操作の主役はJPQL 1 2 3 4 4
  • 5. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 内容 JPAの仕組み いろいろなエンティティマッピング オブジェクト関係マッピング 操作の主役はJPQL 1 5 2 3 4
  • 6. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 1. JPA(Java persistent API)の役割と効果 6 オブジェクトの世界 データベース(RDB)の世界JPA キーカラムで関連するテーブルを結合する INFORMATION テーブルのキー
  • 7. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 1. JPA(Java persistent API)の役割と効果 7 オブジェクトの世界 データベース(RDB)の世界JPA 参照でオブジェクトを関連付ける Informationオブジェクトの参照
  • 8. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 1. JPA(Java persistent API)の役割と効果 8 オブジェクトの世界 データベース(RDB)の世界JPA ・変換指定(マッピング)はアノテーションだけでOK ・Javaオブジェクトをそのまま、読み・書き・削除・検索などできる ・オブジェクト指向の問い合わせ言語(JPQL)が使える ・JPQLと同等なAPIも使える JavaオブジェクトとRDB(レコード、テーブル)との自動変換
  • 9. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 9 2. すべての操作を行うEntityManger エンティティマネージャーを使ってデータベース処理を実行する
  • 10. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 10 2. すべての操作を行うEntityManger エンティティマネージャーを使ってデータベース処理を実行する
  • 11. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 11 2. すべての操作を行うEntityManger エンティティマネージャーを使ってデータベース処理を実行する
  • 12. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 12 3. エンティティの作成(基本) エンティティ=データベースに保管するオブジェクト エンティティクラスの要件 ① クラスに@Entityを付ける ② 主キーの項目に@idを付ける ③ publicで引数のないコンストラクタを持つ ④ カプセル化する ⑤ final修飾子をクラスやフィールドに使わない
  • 13. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 13 3. エンティティの作成(基本) import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.NotNull; @Entity public class Employee implements Serializable { @Id @NotNull private Integer number; // 社員番号 private String name; // 氏名 private String mail; // メール public Employee(){} public Employee(Integer number, String name, String mail){ ・・・ ・・・ } // セッター、ゲッター(省略) }
  • 14. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 14 3. エンティティの作成(基本) import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.NotNull; @Entity public class Employee implements Serializable { @Id @NotNull private Integer number; // 社員番号 private String name; // 氏名 private String mail; // メール public Employee(){} public Employee(Integer number, String name, String mail){ ・・・ ・・・ } // セッター、ゲッター(省略) } ビーンバリデーションも指定できる @NotNull ---- Null禁止
  • 15. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 15 3. エンティティの作成(基本) import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.NotNull; @Entity public class Employee implements Serializable { @Id @NotNull private Integer number; // 社員番号 private String name; // 氏名 private String mail; // メール public Employee(){} public Employee(Integer number, String name, String mail){ ・・・ ・・・ } // セッター、ゲッター(省略) } 実用上は、 インスタンスを作成するためのコンストラク タも作っておく
  • 16. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 16 3. エンティティの作成(基本) import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.NotNull; @Entity public class Employee implements Serializable { @Id @NotNull private Integer number; // 社員番号 private String name; // 氏名 private String mail; // メール public Employee(){} public Employee(Integer number, String name, String mail){ ・・・ ・・・ } // セッター、ゲッター(省略) } Netbeansで自動生成 ① エディタ上で右ボタン ②[コードを挿入]を選択 ③[取得メソッドおよび設定メソッド]を選択
  • 17. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 17 4. EntityManger の機能 エンティティマネージャーを使ってデータベース処理を実行する
  • 18. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 18 4. EntityManagerの機能 メソッド 機 能 void persist(Object e ) エンティティeをデータベースに新規登録する E merge( E e) データベースの中のエンティティを引数のエンティティeで更新する void remove(Object e) エンティティeを(データベースから)削除する E find(E.class, Object key) key(主キー)で検索して発見したエンティティを返す E getReference(E.class, Object key) findと同様だが遅延フェッチする void refresh(Object e) 永続性コンテキストにあるエンティティeをデータベースから取得した値で更新 void clear() 永続性コンテキストをクリアし、エンティティを永続性コンテキストから分離 void flush() 永続性コンテキストにあるエンティティを即時にデータベースと同期する void detach(Object e) 引数のエンティティを、永続性コンテキストから分離する boolean contains(Object e) 引数に指定したエンティティが永続性コンテキストの中にあるかどうか調べる javax.persistence パッケージ interface EntityManager ※Eはエンティティの型を表し、Class<E>をE.classと表記しています。
  • 19. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 19 @stateless public class Db { @PersistenceContext private EntityManager em; public void create(Employee obj){ em.persist(obj); // 挿入 } public void update(Employee obj){ em.merge(obj); // 更新 } ・・・・・・・・ } EJBのクラスで使用する トランザクション管理を EJBコンテナがやってくれ るので、単に永続性コン テキストを相手にして、 読み書き、検索を行えば よい。 commit、rollback、などは EJBコンテナが自動的に行 う。 エンティティマネージャーはDIで取得する 4. EntityManagerの機能<使い方>
  • 20. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 20 6. CRUDのための汎用クラス @stateless public class Db { @PersistenceContext private EntityManager em; public void create(Employee obj){ em.persist(obj); } public void update(Employee obj){ em.merge(obj); } ・・・・・・・・ } エンティティごとにこのような EJBが必要なので、いくつもの エンティティを使う時、とても 面倒。
  • 21. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 21 6. CRUDのための汎用クラス public class Db<T> { @PersistenceContext private EntityManager em; public void create(T obj) { em.persist(obj); } public void update(T obj) { em.merge(obj); } ・・・・・・・・ } どんな型のエンティティでも処 理できるように、総称型のスー パークラスを使っておく。 @stateless public class EmployeeDb extends Db<Employee>{ } エンティティごとにこれだ け書けばよい。
  • 22. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 22 6. CRUDのための汎用クラス public class Db<T> { private Class<T> cl; //型情報 @PersistenceContext private EntityManager em; public Db(Class<T> cl){ this.cl = cl; } public void create(T obj) { em.persist(obj); } public T find(Object id) { return em.find(cl, id); } ・・・・・・・・ } 検索系のメソッドでは、エン ティティの型情報も必要なので、 コンストラクタで受け取るよう に修正。 クラス型
  • 23. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 23 例えば、EmployeeDb ← Employeeエンティティの処理クラス 6. CRUDのための汎用クラス @stateless public class EmployeeDb extends Db{ public EmployeeDb(){ super(Employee.class); } } 結局、エンティティごと にこれだけ書けばよい。 @EJB EmployeeDb db; ・・・ メソッドの中で Employee e = new Employee(・・・) db.create(e); このように使う
  • 24. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 24 6. CRUDのための汎用クラス メソッド名 機 能 public void create(T entity) 新規登録する public void edit(T entity) 更新する public void delete(T entity) 削除する public T find(Object id) キーによる検索 public List<T> findAll() 全件を取得する public List<T> findRange(int[] range) range[0]からrange[1]の範囲のエンティ ティを取得 public int count() 全件数を返す ※ http://k-webs.jp/JavaEE/ からダウンロードできます
  • 25. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 25 7. エンティティのライフサイクル エンティティマネージャーを使ってデータベース処理を実行する
  • 26. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 26 7. エンティティのライフサイクル 永続性コンテキスト 管理状態 管理状態 管理状態 管理状態 RDB 削除状態 分離状態 persist() merge() find() remove() detach() clear() RDBとの同期 ・トランザクション終了時 ・クエリ発行時 ・flash()メソッド実行時 ・reload()メソッド実行時 デフォルトでエンティティ をキャッシュする。
  • 27. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 27 メソッド 本来の意味 persist 新しくエンティティを管理対象にする merge detachしたエンティティなど対象外のエンティティを再度管理対象とする remove エンティティを削除対象にする find IDによってエンティティを検索し管理対象にする detach 引数で指定されたエンティティを管理対象外(分離)にする clear 全てのエンティティを管理対象外にする 6. エンティティのライフサイクル ★ メソッドは「対象にする」だけで、RDBとの同期はエンティティマネージャーが管理している @stateless public class Db { @PersistenceContext private EntityManager em; public void save(Employee obj){ em.persist(obj); obj.setName(“鈴木”); }
  • 28. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 28 7. 永続性ユニットとデータベース接続 <データベースサーバー> ① データベースを作成する(ex. mydb) <アプリケーションサーバー> ② RDBのJDBCのドライバを置く ③ コネクションプールとデータソース を登録する <アプリケーション> ④ データベース接続情報を作成する (永続性ユニット=persistence.xml) 事前に1回だけ
  • 29. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 29 7. 永続性ユニットとデータベース接続 <データベースサーバー> ① データベースを作成する(ex. mydb) <アプリケーションサーバー> ② RDBのJDBCのドライバを置く ③ コネクションプールとデータソース を登録する <アプリケーション> ④ データベース接続情報を作成する (永続性ユニット=persistence.xml) アプリケーション毎に
  • 30. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 30 7. 永続性ユニットとデータベース接続 アプリケーション は永続性ユニット の情報により、 データベースにア クセスする。 複数の永続性 ユニットを作って、 複数のデータ ベースをハンドリ ンクできる。
  • 31. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 31 7. 永続性ユニットとデータベース接続(JavaEE) IDEは、永続性ユニット(persistence.xml)を自動生成 する機能がある。 NetBeansでは、サーバーにコネクションプールやデー タソースが作成されていない場合、その作成処理も 合わせて行うことができる。 右の動画で、MySQLをインストール直後、ee7 という 名前のデータベースを作成し、アプリケーションで使 用できるようにする設定手順を示す。
  • 32. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 32 @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); db.create(emp); return null; } // セッター、ゲッター } 8. JPAの使い方 (EE) JavaEE で、ウェブ画面で入力したデータ を受け取ってデータベースに書き込む処理 を説明する。
  • 33. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 33 @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); db.create(emp); return null; } // セッター、ゲッター } 8. JPAの使い方 (EE) フィールドの各項目は、プログラムの変数 に バインド(結合)されている。
  • 34. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 34 @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); db.create(emp); return null; } // セッター、ゲッター } 8. JPAの使い方 (EE) このようなウェブは JSF で作成し、データ を受け取るプログラムをバッキングビーン という。 バッキングビーン
  • 35. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 35 @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); db.create(emp); return null; } // セッター、ゲッター } 8. JPAの使い方 (EE) JSFでは、ボタンを押したとき起動するメ ソッドを指定できる。例では、登録ボタン を押すと create メソッドが起動する。 バッキングビーン
  • 36. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 36 @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); db.create(emp); return null; } // セッター、ゲッター } 8. JPAの使い方 (EE) バッキングビーン create メソッドは、ウェブから受け取った データで、Employeeエンティティ(オブ ジェクト)を作成し、db.create でデータ ベースに登録する。 db はEJB(Enterprise Java Beans)なのでDI で取得する。
  • 37. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); db.create(emp); return null; } // セッター、ゲッター } @Stateless public class EmployeeDb { @PersistenceContext private EntityManager em; public void create(Employee emp) { em.persist(emp); } } 37 8. JPAの使い方 (EE) DI でエンティティマ ネージャを取得する データベースに登録する データベース処理は EJB に書く。 EJBコンテナがデータベースのトランザク ション処理を管理してくれるので、記述 が簡単になる。 begin, commit, close, rollback など不要。 バッキングビーン
  • 38. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @Named @RequestScoped public class Bb { private Integer number; private String name; private String mail; @EJB EmployeeDb db; public String create() { Employee emp = new Employee(number, name, mail); try { db.create(emp); }catch(Exception e){ // 例外処理 } return null; } // セッター、ゲッター } 38 8. JPAの使い方 (EE) バッキングビーン 新規データの書き込みで、すでに同じ キーを持つデータが存在している場合な どは例外が発生する。例外処理が必要な 場合は、try-catch の中でEJBのメソッドを 呼び出す。
  • 39. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 内容 JPAの仕組み いろいろなエンティティマッピング オブジェクト関係マッピング 操作の主役はJPQL 1 39 2 3 4 ※ 動かせる例題プロジェクトを http://k-webs.jp/JavaEE/ からダウンロードできます
  • 40. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 40 ① エンティティのクラス名をテーブル名とする ② フィールド変数名をテーブルのカラム名とする ③ データ型はRDBの種類で若干異なる名前になる 1. デフォルトのマッピング (設定より規約) @Entity public class Employee { @id private Integer number; private String name; ・・・ } [PK] NUMBER NAME EMPLOYEE テーブル
  • 41. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 41 1. デフォルトのマッピング (設定より規約) アノテーションによりデフォルトのマッピングを変更できる 1. テーブルの構成 を指定するアノテーション 2. 主キーの構成 を指定するアノテーション 3. フィールド に個別の属性を指定するアノテーション 4. その他のアノテーション
  • 42. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 42 2. テーブルの構成を指定するアノテーション 1 @Table RDBのテーブル名を指定する 2 @Secondarys @Secondary @Column エンティティを複数のRDBテーブルに分割する 3 @Embeddable @Embedded 複数のクラスからひとつのエンティティを構成 する
  • 43. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 43 2. テーブルの構成を指定するアノテーション 1 @Table RDBのテーブル名を指定する 2 @Secondarys @Secondary @Column エンティティを複数のRDBテーブルに分割する 3 @Embeddable @Embedded 複数のクラスからひとつのエンティティを構成 する
  • 44. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 44 2. テーブルの構成を指定するアノテーション 1 @Table RDBのテーブル名を指定する 2 @Secondarys @Secondary @Column エンティティを複数のRDBテーブルに分割する 3 @Embeddable @Embedded 複数のクラスからひとつのエンティティを構成 する
  • 45. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 45 2-1. RDBのテーブル名を指定する @Entity @Table(name = "EMP_TBL") public class Employee implements Serializable { @Id @NotNull private String id; private String eval; private String name; ・・・ } @Table により、RDBの テーブル名を指定する。 テーブル名は EMPLOYEE ではなく EMP_TBL になる 積極的に使用する。 SQLの予約語と衝突 しないよう、末尾 に_TBLなどを付け るのがよい。
  • 46. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 46 2-2. エンティティを複数のテーブルに分ける @Entity @SecondaryTables({ @SecondaryTable(name = "ADDRESS"), @SecondaryTable(name = "SKILL") }) public class Employee1 implements Serializable { @Id private String id; @Column(table = "ADDRESS") private String city; @Column(table = "SKILL") private String eval; private String name; ・・・ } @Columnを使って、 city を ADDRESS テーブ ルに、eval を SKILL テー ブルに割り当てる。 分割先のテーブル名を 指定する。 @SecondaryTableを複数 指定できる
  • 47. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 47 2-2. エンティティを複数のテーブルに分ける @Entity @SecondaryTables({ @SecondaryTable(name = "ADDRESS"), @SecondaryTable(name = "SKILL") }) public class Employee1 implements Serializable { @Id private String id; @Column(table = "ADDRESS") private String city; @Column(table = "SKILL") private String eval; private String name; ・・・ } EMPLOYEE1 ADDRESS SKILL 3つのテーブルが できる
  • 48. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 48 2-3. 複数のクラスからエンティティを構成する @Entity public class Employee2 implements Serializable { @Id private Long id; private String name; @Embedded private Tel tel; ・・・ } @Embeddable public class Tel implements Serializable { private String telephone; private String cellular; ・・・ } @Embeddedで、 フィールドに合成する 他のクラスを指定する。 @Embeddedは複数指 定できる。 エンティティの一部に なるクラスには、 @Embeddable を付ける String telephone; String cellular; ※ 2項目に展開される
  • 49. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 49 3. 主キーを指定するアノテーション 1 @Id @GeneratedValue 主キーの自動生成を指定する 2 @Embeddable @EmbeddedId @Embeddableを付けたクラスのオブジェクトを 主キーにする。 3 @IdClass @Id @IdClassを付けたクラスのオブジェクトを主 キーにする。
  • 50. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 50 3. 主キーを指定するアノテーション 1 @Id @GeneratedValue 主キーの自動生成を指定する 2 @Embeddable @EmbeddedId @Embeddableを付けたクラスのオブジェクトを 主キーにする。 3 @IdClass @Id @IdClassを付けたクラスのオブジェクトを主 キーにする。
  • 51. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 51 3. 主キーを指定するアノテーション 1 @Id @GeneratedValue 主キーの自動生成を指定する 2 @Embeddable @EmbeddedId @Embeddableを付けたクラスのオブジェクトを 主キーにする。 3 @IdClass @Id @IdClassを付けたクラスのオブジェクトを主 キーにする。
  • 52. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 52 3. 主キーを指定するアノテーション 1 @Id @GeneratedValue 主キーの自動生成を指定する 2 @Embeddable @EmbeddedId @Embeddableを付けたクラスのオブジェクトを 主キーにする。 3 @IdClass @Id @IdClassを付けたクラスのオブジェクトを主 キーにする。 ※ 2と3は、エンティティで主キーに指定する方法が違うだけで、実質は同じ。 2の方法が簡単でよい。
  • 53. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 53 3-1. 主キーの自動生成を指定する @Entity public class Employee3 implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id ; private String name; ・・・ } 主キーの生成方法を、 @GeneratedValueで指定。 GenerationType.AUTO 使用しているデータベースシステムの既定の方法を使う GenerationType.TABLE SQLシーケンス名と現在値を格納したテーブルを使って自動生成する GenerationType.SEQUENCE データベースのSQLシーケンスを使って自動生成する GenerationType.IDENTITY データベースのIDカラムの値を主キーの値とする 普通はAUTOを指定する 主キーを自動生成
  • 54. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 54 3-2. 別のクラスのオブジェクトを主キーにする 主キーにするクラスに @Embeddableを付ける @Entity public class Employee4 implements Serializable { @EmbeddedId private CompositeKey id; // 主キー private String name; ・・・ } @EmbeddedIdでクラス オブジェクトを主キー に指定する @Embeddable public class CompositeKey implements Serializable { private String groupId; private String userId; ・・・ }
  • 55. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 55 3-3. 別のクラスのオブジェクトを主キーにする public class CompositeKey implements Serializable { private String groupId; private String userId; ・・・ } 主キーにするクラスは アノテーション不要 @Entity @IdClass(CompositeKey.class) public class Employee5 implements Serializable { @Id private String groupId; @Id private String userId; private String name; @Idで主キー項目を指定 全てのフィールドを同 じ名前でもれなく指定 すること。 @IdClassで主キーにする クラスを指定
  • 56. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 56 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値の記録形式を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 57. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 57 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値の記録形式を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 58. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 58 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値の記録形式を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 59. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 59 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値の記録形式を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 60. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 60 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値の記録形式を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 61. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 61 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値の記録形式を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 62. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 62 4.フィールド に個別の属性を指定するアノテーション 1 @column フィールドに対応するテーブルカラムを指定する 2 @Basic @Lob 遅延フェッチを指定できる ファイルなど大きいデータであることを示す 3 @Enumerated 列挙を名前と序数のどちらで記録するか指定 4 @TemporalType Date, Calendar型の値のデータベース型を指定 5 @ElementCollection @CollectionTable @MapKeyColumn @Column 基本型のList, Set, MapをRDBに割り付ける 割り付け先のテーブル名を指定する 割り付け先テーブルでのキーカラム名を指定 割り付け先テーブルでのカラム名を指定 6 @Transient データベースに保存しないフィールドを指定
  • 63. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 63 @Entity public class Employee implements Serializable { @Id @Column(name = “E_ID", nullable = false, length=50) private Integer id; @Column(name=“E_VALUE", updatable=false, precision=12, scale=2) public BigDecimal val; ・・・ } テーブルのカラム名 null にできない 長さは50文字 値を更新できない 12桁の精度 整数部2桁 4-1. @Column フィールドの属性を指定する。 テーブルを生成する際に適用される。
  • 64. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 64 @Entity public class Employee implements Serializable { @Lob @Basic(fetch=LAZY) private byte[] picture; ・・・ @Lob @Basic(fetch=EAGER) protected String report; @Basic(Optional=false) private Book book; } ラージオブジェクト 4-2. @Lob @Basic 遅延フェッチする(レコード読出し時には空で、 実際に、フィールドの値が使われる時、値を取り出す。 nullを入れることができない 即座にフェッチする(既定値)
  • 65. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 65 public enum GroupColor {GREEN, BLUE, RED} public enum Employee_Status {FULL_TIME, PART_TIME, CONTRACT} @Entity public class Employee implements Serializable { @Enumerated(ODINAL) private GroupColor color; @Enumerated(String) private Employee_Status status; } 4-3. @Enumerated 列挙を数値で記録する(既定値) 文字列で記憶すると、列挙の内容を変更しても安全。 列挙を文字列で記録する 列挙型
  • 66. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 66 @Entity public class Employee implements Serializable { @Temporal(TIMESTAMP) private Date dateTime; @Temporal(TIME) private Date startTime; @Temporal(DATE) private Calendar birthday; } 4-4. @Temporal 年月日 時分秒 時分秒 年月日 java.util.Date と java.util.Calendar には必ず指定しなければならない。 指定を忘れると、例外を発 生して、デプロイできなく なります。
  • 67. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 67 @Entity public class Employee implements Serializable { @Id private Long id; private String name; @ElementCollection private List<String> notes; @ElementCollection private Map<Integer, String> items; } 4-5. @ElementCollection List @ElementCollectionで、Collection、List、Set、Mapをデータベースに割り付ける フィールド ・Collection List Set ・Map ただし、要素は、Stringや 基本データ型のラッパーク ラスに限る。 Map
  • 68. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 4-5. @ElementCollection EMPLOYEE ID NAME 100 田中 200 鈴木 EMPLOYEE_NOTES EMPLOYEE_ID NOTES 100 A商店 100 B商店 200 C商店 EMPLOYEE_ITEMS EMPLOYEE_ID ITEMS ITEMS_KEY 100 ビール 1 100 ウィスキー 2 200 ビール 1 200 焼酎 3 @Id private Long id; private String name; @ElementCollection private List<String> notes; @ElementCollection private Map<Integer, String> items; テーブル名、カラム名 は規約により決定。
  • 69. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 4-5. @ElementCollection テーブル名、カラム名を変更するには他のアノテーションを追加する @CollectionTable @Column @MapKeyColumn 割り付け先のテーブル名を指定する 割り付け先テーブルでのカラム名を指定 割り付け先テーブルでのキーカラム名を指定
  • 70. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 4-5. @ElementCollection NOTE_TBL EMPLOYEE_ID MEMO 100 A商店 100 B商店 200 C商店 ITEM_TBL EMPLOYEE_ID NAME NUMBER 100 ビール 1 100 ウィスキー 2 200 ビール 1 200 焼酎 3 @Id private Long id; private String name; @ElementCollection @CollectionTable(name="NOTE_TBL") @Column(name="MEMO") private List<String> notes; @ElementCollection @CollectionTable(name="ITEM_TBL") @Column (name="NAME") @MapKeyColumn (name="NUMBER") private Map<Integer, String> items;
  • 71. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 71 @Entity public class Employee implements Serializable { @Transient private int flag; } ※シリアライズしない変数につける transient 修飾子と似ている 4-6. @Transient データベースに保存しないフィールドを指定
  • 72. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 内容 JPAの仕組み いろいろなエンティティマッピング オブジェクト関係マッピング 操作の主役はJPQL 1 72 2 3 4
  • 73. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 5つのパターン ① One-to-One ② One-to-Many ③ One-to-One(双方向) ④ One-to-Many、Many-to-One (双方向) ⑤ Many-to-Many (双方向) 73
  • 74. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 74 1. One-to-One (1対1の関係) 顧客(ID、名前、顧客情報) 顧客情報(ID、住所、電話、携帯) 必ず1対1に対応する
  • 75. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 75 1. One-to-One (1対1の関係)  エンティティの定義 @Entity public class Customer implements Serializable { @Id private String customerId; private String name; private Information info; ・・・・・ @Entity public class Information implements Serializable { @Id @GeneratedValue(strategy =GenerationType.AUTO) private Long id; private String address; private String phone; private String cellular; ・・・・・顧客情報オブジェクト
  • 76. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 76 @EJB InformationDb infoDb; @EJB CustomerDb cusDb; ・・・・・・ public void write(){ } データベースに保存処理 1. One-to-One (1対1の関係)  永続化(データベース)処理 汎用CRUDクラスから作成したそれぞれの エンティティ用のEJBをDIで取得しておく 具体的な処理はここに書く
  • 77. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 77 Information info1 = new Information("東京都", "03-333-3333", "090-333-3333"); Customer c1 = new Customer("cus001", "田中宏", info1); infoDb.create(info1); cusDb.create(c1); データベースに保存 1. One-to-One (1対1の関係)  永続化(データベース)処理 それぞれをDBに保存 顧客情報も忘れずに
  • 78. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 78 外部キー結合:外部キーで関連するテーブルを結合する INFORMATION テーブルのキー 1. One-to-One (1対1の関係)  RDBでの保存形式は次のようになる
  • 79. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 79 Information info1 = new Information("東京都", "03-333-3333", "090-333-3333"); Customer c1 = new Customer("cus001", "田中宏", info1); infoDb.create(info1); cusDb.create(c1); データベースに保存 1. One-to-One (1対1の関係)  カスケード処理 どちらか1つだけ保存すればよいようにしたい
  • 80. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 80 @Entity public class Customer implements Serializable { @Id private String customerId; private String name; @OneToOne(cascade = {CascadeType.ALL}) private Information info; ・・・・・ 1. One-to-One (1対1の関係)  カスケード処理 @Entity public class Information implements Serializable { @Id @GeneratedValue(strategy =GenerationType.AUTO) private Long id; private String address; private String phone; private String cellular; ・・・・・ DB操作をする方にカスケードを指定する
  • 81. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 81 Information info1 = new Information("東京都", "03-333-3333", "090-333-3333"); Customer c1 = new Customer("cus001", "田中宏", info1); cusDb.create(c1); データベースに保存 1. One-to-One (1対1の関係)  カスケード処理 これだけでOK!
  • 82. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 82 カスケード指定 カスケードするイベント 対応するメソッド CascadeType.PERSIST 新規保存 persist CascadeType.MERGE 更新 merge CascadeType.REMOVE 削除 remove CascadeType.REFRESH 永続性コンテキストのエンティティをデータベー スから再取得した値で更新 refresh CascadeType.DETACH 永続性コンテキストからエンティティを分離する detach CascadeType.ALL 上記のすべての操作 使用例: @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) 1. One-to-One (1対1の関係)  カスケード処理 ALL以外では、必要なものだけを指定できる
  • 83. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 1. One-to-One (1対1の関係) ① DB操作を実行する方に、 @OneToOne(cascade={~})を付ける 【要点】
  • 84. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 5つのパターン ① One-to-One ② One-to-Many ③ One-to-One(双方向) ④ One-to-Many、Many-to-One (双方向) ⑤ Many-to-Many (双方向) 84
  • 85. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 85 2. One-to-Many (1対多の関係) 注文(ID、顧客、注文明細) 注文明細(ID、品名、数量、日付) 1つの注文に複数の注文明細が対応する
  • 86. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 86 2. One-to-Many (1対多の関係)  エンティティの定義 @Entity public class Cart implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long cartID; private String customer; private List<OrderLine> orderLines; ・・・・・ @Entity public class OrderLine implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long orderLineId; private String item; private int quantity; @Temporal(TemporalType.DATE) private Date orderDate; ・・・・・ これでOKですが、さらにカスケードしたいので・・・
  • 87. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 87 2. One-to-Many (1対多の関係)  エンティティの定義 @Entity public class Cart implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long cartID; private String customer; @OneToMany(cascade = {CascadeType.ALL}) private List<OrderLine> orderLines; ・・・・・ @Entity public class OrderLine implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long orderLineId; private String item; private int quantity; @Temporal(TemporalType.DATE) private Date orderDate; ・・・・・ cascadeは、DB操作を実行する方に設定する @OneToManyの中にカスケードを指定する
  • 88. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | ① DB操作を実行する方に、カスケード指定をする @OneToMany(cascade={~})または @ManyToOne(cascade={~}) 【要点】 2. One-to-Many (1対多の関係)
  • 89. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 5つのパターン ① One-to-One ② One-to-Many ③ One-to-One(双方向) ④ One-to-Many、Many-to-One (双方向) ⑤ Many-to-Many (双方向) 89
  • 90. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 90 3. One-to-One (1対1の関係) + 双方向 顧客(ID、名前、顧客情報) 顧客情報(ID、住所、電話、携帯) 必ず1対1に対応するが、双方が互いの参照を持ち合う関係(双方向)
  • 91. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 91 1. One-to-One (1対1の関係) + 双方向  エンティティの定義 @Entity public class Customer implements Serializable { @Id private String customerId; private String name; @OneToOne(cascade = {CascadeType.ALL}) private Information info; ・・・・・ @Entity public class Information implements Serializable { @Id @GeneratedValue(strategy =GenerationType.AUTO) private Long id; private String address; private String phone; private String cellular; @OneToOne(mappedBy=“info”) private Customer customer; ・・・・・ 1方向の関係が2つにならないように、どちらかに mappedBy を指定する 関係の被所有者 関係の所有者
  • 92. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 3. One-to-One (1対1の関係) + 双方向 【要点】 ① DB操作を実行する方に、 @OneToOne(cascade={~})を付ける ② どちらか一方にだけ @OneToOne(mappedBy=~)を付ける 付けた方は<関係の被所有者>、相手方は<関係の所有者>
  • 93. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 5つのパターン ① One-to-One ② One-to-Many ③ One-to-One(双方向) ④ One-to-Many、Many-to-One (双方向) ⑤ Many-to-Many (双方向) 93
  • 94. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 注文(ID、顧客、注文明細) 注文明細(ID、品名、数量、日付) 94 4. One-to-Many と Many-to-One の 双方向 1つの注文に複数の注文明細が対応する。注文明細からもどの注文に属するかわかる(双方向)
  • 95. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @Entity public class OrderLine implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long orderLineId; private String item; private int quantity; @Temporal(TemporalType.DATE) private Date orderDate; private Cart cart; ・・・・・ 95  エンティティの定義 @Entity public class Cart implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long cartID; private String customer; @OneToMany(mappedBy=“cart”, cascade= {CascadeType.ALL}) private List<OrderLine> orderLines; ・・・・・ One-To-Many 側に mappedBy を付ける 関係の被所有者=One-to-Many側 関係の所有者=Many-to-One 側 4. One-to-Many と Many-to-One の 双方向
  • 96. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 【要点】 ① DB操作を実行する方に、 カスケード指定を付け る ② One-to-Many側に@OneToMany(mappedBy=~)を付ける 4. One-to-Many と Many-to-One の 双方向
  • 97. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 5つのパターン ① One-to-One ② One-to-Many ③ One-to-One(双方向) ④ One-to-Many、Many-to-One (双方向) ⑤ Many-to-Many (双方向) 97
  • 98. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 98 5. Many-to-Many 双方向 (1方向はない) 俳優=多くの映画に出演 (ID、顧客、映画のリスト) 映画=多くの俳優が出演 (ID、タイトル、出演俳優のリスト) それぞれが、相手の多数と関係がある(多対多、双方向)
  • 99. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @Entity public class Movie implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; private List<Actor> actors; ・・・・・ 99 5. Many-to-Many 双方向 (1方向はない)  エンティティの定義 @Entity public class Actor implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; @ManyToMany(mappedBy="actors“) private List<Movie> movies; ・・・・・ 2つの1対多関係とならないように、どちらかに mappedBy を付ける(どちらでもよい)
  • 100. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 【要点】 ① どちらかに @ManyToMany(mappedBy=“・・・”) を付ける ※エンティティの両方に、 カスケード指定、cascade={CascadeType.PERSIST} を付けないと 保存できないという問題がありました。 5. Many-to-Many 双方向 (1方向はない)
  • 101. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 内容 JPAの仕組み いろいろなエンティティマッピング オブジェクト関係マッピング 操作の主役はJPQL 1 101 2 3 4
  • 102. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 102 1. JPQL(Java Persistence Query Language)の位置付け 問い合わせの方法 特 徴 JPQL SQLと似ている どのDB製品でも共通の命令を使える オブジェクト指向(Javaの変数名、自動的なJOIN) Native Query SQLをそのまま適用 Criteria API JPQLと同等の問い合わせをプログラムできる 動的にクエリを組み立てることができる 型チェックが働くので間違いが減る 記述は面倒
  • 103. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 注文(ID、顧客、注文明細) 注文明細(ID、品名、数量、日付) 103 この章で対象とするエンティティ(One-to-Many 双方向) 1. JPQL(Java Persistence Query Language)の位置付け
  • 104. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 104 2. JPQLの文法 (1/5) select c from Cart c select c from Cart c where c.name = ‘田中’ ・クエリの基本形 ・c はエンティティの別名(エイリアス) ・select 句にエイリアスを指定すると、全件を取得する意味になる ・where句などでは、エイリアスのプロパティ(フィールド名)を使って記述する 演算子 備 考 = c.name=’山田' >, >= c.price>1000 <, <= c.price<=500 <> c.price <> 1000 BETWEEN c.price BETWEEN 100 and 1000 演算子 備 考 LIKE 文字列の一致を検査する IN ()内のリストに該当があるか IS NULL IS EMPTY AND OR NOT ()
  • 105. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 105 2. JPQLの文法 (2/5) select o from OrderLine o where o.cart.customer = '田中宏' 関係のあるエンティティでは自動的にJOINが働く 本来なら、join を使って次のように書くところ。 select o from OrderLine o join Cart c on o.cart.cartID = c.cartID where o.cart.customer = '田中宏' select count(c) from Cart c where c.customer = ‘田中’ select o.item, max(o.quantity) from OrderLine o 集計関数も使える 全ての関数は次のURLにマニュアルがある https://docs.oracle.com/javaee/7/tutorial/persistence-querylanguage005.htm#BNBVP Customerの値は Cartテーブルから取り出している
  • 106. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 106 2. JPQLの文法 (3/5) Object[] array = select c.customer, count(c) from OrderLine o join Cart c on o.cart = c group by c ・エンティティ以外の結果は、Object[] 型になり、キャストが必要で記述が面倒 顧客ごとの、顧客名と注文の件数を得る
  • 107. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 107 2. JPQLの文法 (3/5) List<Sum> ls = select new beans.Sum(c.customer, count(c)) from OrderLine o join Cart c on o.cart = c group by c ・エンティティ以外の結果は、Object[] 型になり、キャストが必要で記述が面倒 ・結果をマップするクラスを作成しておいて、そのオブジェクトに受け取ると便利 package bean; public class Sum{ private String name; private long count; public Sum(String name, long count){ this.name = name; this.count = count; } // セッター、ゲッター等 } エンティティでなく、普通の クラスでよい。 List<Sum> で結果を受け取 れる。 コンストラクタで受ける
  • 108. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 108 2. JPQLの文法 (4/5) select distinct c from Cart c join fetch c.orderLines CartとそのOrderLine(複数)を一度に取得するSQLを生成する One-to-Manyの関係でのN+1問題(=Cartから全データを取得すると、CartエンティごとにOrderlineエン ティを取得するSQLが生成される)に対応する書き方 select c from Cart c select distinct c from Cart c join fetch c.orderLines Cartを取得 Cartが持つ OrderLine を取得 SQL がひとつだけになった One-to-Many は 遅延フェッチ(LAZY) がデフォルト
  • 109. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 109 ★JPQL実行時に、実行されたSQLログを取る設定
  • 110. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 110 2. JPQLの文法 (5/5) update OrderLine o set o. quantity = 10 where o.cart.customer = ‘田中宏’ エンティティの一括更新 delete from OrderLine o where o. orderDate = ‘2019-01-04’ エンティティの一括削除
  • 111. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | 111 3. JPQLの実行方法 JPQLの実行方法の種類 動的クエリ JPQLをそのまま実行する (簡単だが効率はよくない) 名前付きクエリ エンティティの中にJPQLを作成して名前を付けておき その名前を使って実行する @Stateless public class MyDbOperation{ @PersistenceContext private EntityManager em; List<Cart> getCartAll(){ } ・・・・・・ } JPQLを実行(ここではCartの全件検索処理) EJBのクラスを作成して、 その中でJPQLを実行する。
  • 112. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @NamedQueries ({ @NamedQuery(name= OrderLine.ALL, query="select o from OrderLine o where o.item= :itemName"), @NamedQuery(name=OrderLine.ALL_DESC, query="select o FROM OrderLine o order by o.quantity desc") }) @Entity @Table(name = "ORDERLINE_TBL") public class OrderLine implements Serializable { public static final String ALL = "ALL"; public static final String ALL_DESC = "ALL_DESC"; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long orderLineId; ・・・・・・ 112 4. 名前付きクエリの作成 ソート指定 。 desc(降順)、asc(昇順) asc が既定値 名前をエンティティクラスのstatic変数にしておく。 EJBのプログラムで名前を書き間違うと、コンパイル エラーになるので分かる。 パラメータ 値は実行時にセットできる
  • 113. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @Stateless public class MyDbOperation { @PersistenceContext private EntityManager em; public List<OrderLine> orderLines(String item){ TypedQuery<OrderLine> q = em.createNamedQuery(OrderLine.ALL,OrderLine.class); q.setParameter("itemName", item); return q.getResultList(); } ・・・・・ } 113 5. EJBを作成(実行メソッドの作成) "select o from OrderLine o where o.item= :itemName" JPQL文字列 クラス型 return em.createNamedQuery(OrderLine.ALL,OrderLine.class) .setParameter("itemName", "ビール") .getResultList(); メソッドチェーン可能
  • 114. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @Stateless public class MyDbOperation { @PersistenceContext private EntityManager em; public List<OrderLine> orderLines(String item, int s, int n){ return em.createNamedQuery(OrderLine.ALL,OrderLine.class) .setParameter("itemName", "ビール") .setFirstResult(s) .setMaxResult(n) .getResultList(); } ・・・・・ } 114 5. EJBを作成(実行メソッドの作成) s件目から読み込む 最高n件だけ読み込む ページ制御ができる http://k-webs.jp:8080/pagination/
  • 115. Copyright © 2015, Oracle and/or its affiliates. All rights reserved. | @EJB MyDbOperation dao; ・・・・・・ public List<OrderLine> getOrderLine(){ return dao.orderLines("ビール"); } 115 6. 名前付きクエリを実行 バッキングビーンでは、EJBをDIで取得し、 クエリを実行して、ウェブに結果を表示 できる。 JavaEEで作成したサンプルプログラムを試せます。 http://k-webs.jp:8080/zakka-ya-san/faces/index.xhtml