[JPA]9枚価格タイプ
この記事は、キム・ヨンハンの『Java ORM標準JPAプログラミング』を読んで学習内容を整理したものだ.デフォルトタイプ 埋め込み 値タイプおよび不変オブジェクト 値タイプ比較 値タイプセット JPAのデータ型を大きく分類すると、エンティティ型と値型に分けられます.
エンティティタイプ @Entity定義のオブジェクト
値のタイプ デフォルト・タイプ Java基本タイプ(int,double,...) Rapperクラス(Integer,...) String 埋め込み コレクション値タイプ 値タイプname、age属性に識別子値はなく、ライフサイクルもメンバーエンティティに依存します. 値タイプは共有できません.
新しい値タイプを直接定義して使用します.
✔¥2のうち1つは省略できます.
imbeddyタイプは、エンティティの値であるため、属するエンティティのテーブルにマッピングされます.
imbeddyタイプを使用する前と後でマッピングされるテーブルは同じです.
埋め込みタイプには、値タイプを含めるか、エンティティを参照できます.エンティティを参照-共有可能 値タイプを含む-特定の所有者に属し、論理概念上は共有しない
埋め込みタイプに埋め込みタイプがある場合でも、エンティティに設定する必要があります.❓
imbeddyタイプがnullの場合、マッピングされたcolumn値はnullです.
imbeddyタイプと同じ値タイプを複数のエンティティで共有することはできません.
デフォルトのタイプ-値をコピーして渡す
オブジェクトタイプ-参照値を渡す
ただし、元の参照値をコピーせずに直接渡すのは止められません.
オブジェクトの共有参照は避けられません.
オブジェクトの値の変更を防止します.
ex)setterのような修正者を削除する方法.
ソースから副作用を防止するために、値タイプはできるだけ不変のオブジェクトとして設計する必要があります.
不変オブジェクトの値はクエリー,変更
不変のオブジェクトも最終的にはオブジェクトです.
*インスタンスの参照値の共有は回避できません.
インスタンスの値は変更できないため、副作用は発生しません.
不変オブジェクトを作成!
モディファイヤを作成せずにジェネレータとして値のみを設定します.
値を変更する必要がある場合は、新しいオブジェクトを作成して使用する必要があります.
コンシステンシ比較:インスタンスの参照値を比較し、==使用 同等比較:インスタンスの値を比較し、equals() を使用
値タイプを比較する場合は、
1つ以上の値タイプを保存するには、コレクションに保存し、
リレーショナル・データベースのテーブルには、カラムのセットを含めることはできません.そのため、個別のテーブルを追加する必要があります.
値タイプのセットに保存された値は、別のテーブルに保存されます.これらの値を変更すると、データベース内の元のデータが見つかりにくくなります.
この問題を解決するために、JPA実施者が値タイプのセットを変更した場合値タイプのセットがマッピングされたテーブルのすべての関連データを削除 現在の値タイプの集合オブジェクトのすべての値をデータベースに再保存します. したがって、値タイプセットがマッピングされたテーブルに大量のデータがある場合は、値タイプセットではなく新しいエンティティを作成し、1対多の関係に設定します.
エンティティタイプ
値のタイプ
1.デフォルトのタイプ
@Entity
public class Member { // 엔티티 타입
@Id @GeneratedValue
private Long id;
private String name; // 값 타입
private int age; // 값 타입
2.埋め込み式
新しい値タイプを直接定義して使用します.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
private int age;
@Embedded Period workPeriod; // 임베디드 타입
}
@Embeddable
public class Period {
@Temporal(TeporalType.DATE) java.util.Date startDate;
...
}
組み込みテクノロジー@Embeddable
:値タイプを定義した場所に表示@Embedded
:使用値タイプの場所に表示✔¥2のうち1つは省略できます.
2.1テーブルマッピング
imbeddyタイプは、エンティティの値であるため、属するエンティティのテーブルにマッピングされます.
imbeddyタイプを使用する前と後でマッピングされるテーブルは同じです.
2.2関連
埋め込みタイプには、値タイプを含めるか、エンティティを参照できます.
@Entity
public class Member {
@Embedded Address address; // 임베디드 타입 포함
@Embedded PhoneNumber phoneNumber; // 임베디드 타입 포함
}
@Embeddable
public class Address {
String street;
String city;
@Embeddable Zipcode zipcode; // 임베디드 타입 포함
...
}
@Embeddable
public class Zipcode {
String zip;
...
}
@Embeddable
public class PhoneNumber {
@ManyToOne PhoneServiceProvider provider // 엔티티 참조
...
}
@Entity
public class PhoneServiceProvider {
@Id String name;
...
}
2.3属性の再定義
@AttributeOverride
:埋め込みタイプで定義されたマッピング情報を再定義します.@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@Embedded Address homeAddress;
@Embedded Address companyAddress; // 주소 추가
}
テーブルにマッピングされたカラム名が重複します.@AttributeOverride
マッピング情報を再定義します.@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@Embedded Address homeAddress;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="city", column=@Column(name = "COMPANY_CITY")),
@AttributeOverride(name="street", column=@Column(name = "COMPANY_STREET")),
@AttributeOverride(name="zipcode", column=@Column(name = "COMPANY_ZIPCODE"))
})
Address companyAddress; // 주소 추가
}
@AttributeOverride
エンティティに設定する必要があります.埋め込みタイプに埋め込みタイプがある場合でも、エンティティに設定する必要があります.❓
2.4 null
imbeddyタイプがnullの場合、マッピングされたcolumn値はnullです.
3.値タイプと不変オブジェクト
3.1共有を参照
imbeddyタイプと同じ値タイプを複数のエンティティで共有することはできません.
member1.setHomeAddress(new Address("OldCity"));
Address address = member1.getHomeAddress();
address.setCity("NewCity"); // 회원1의 address 값을 공유해서 사용 -> 회원1의 주소도 변경
member2.setHomeAddress(address);
これらの副作用を防止するには、値をコピーして使用する必要があります.3.2箱タイプコピー
member1.setHomeAddress(new Address("OldCity"));
Address address = member1.getHomeAddress();
// 회원1의 address 값을 복사해서 새로운 newAddress 값을 생성
Address newAddress = address.clone();
newAddress.setCity("NewCity");
member2.setHomeAddress(newAddress);
imbeddyタイプはjavaの基本タイプではなく、オブジェクトタイプです.デフォルトのタイプ-値をコピーして渡す
オブジェクトタイプ-参照値を渡す
Address a = new Address("OldCity")
Address b = a.clone(); // 항상 복사해서 넘겨야 한다.
// Address b = a // 이렇게 참조만 넘기면 공유 참조의 부작용이 발생한다.
b.setCity("NewCity");
オブジェクトを挿入するたびにインスタンスをコピーして挿入することで、共有参照を回避できます.ただし、元の参照値をコピーせずに直接渡すのは止められません.
オブジェクトの共有参照は避けられません.
オブジェクトの値の変更を防止します.
ex)setterのような修正者を削除する方法.
3.3不変オブジェクト
ソースから副作用を防止するために、値タイプはできるだけ不変のオブジェクトとして設計する必要があります.
不変オブジェクトの値はクエリー,変更
不変のオブジェクトも最終的にはオブジェクトです.
*インスタンスの参照値の共有は回避できません.
インスタンスの値は変更できないため、副作用は発生しません.
不変オブジェクトを作成!
モディファイヤを作成せずにジェネレータとして値のみを設定します.
値を変更する必要がある場合は、新しいオブジェクトを作成して使用する必要があります.
4.比較値タイプ
int a = 10;
int b = 10;
Address a = new Address("가", "나", "다");
Address b = new Address("가", "나", "다");
値タイプを比較する場合は、
a.equals(b)
を使用して同等に比較します.5.値タイプの集合
1つ以上の値タイプを保存するには、コレクションに保存し、
@ElementCollection
、@CollectionTable
を使用します.@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
@Embedded Address homeAddress;
@ElementCollection
@CollectionTable(name = "FAVORITE_FOODS", joinColumns = @JoinColumn(name = "MEMBER_ID"))
@Column(name = "FOOD_NAME")
private Set<String> favoriteFoods = new HashSet<String>();
@ElementCollection
@CollectionTable(name = "ADDRESS", joinColumns = @JoinColumn(name = "MEMBER_ID"))
private List<Address> addressHistory = new ArrayList<Address>();
}
@ElementCollection
:値タイプセット@CollectionTable
:マッピング集合テーブルリレーショナル・データベースのテーブルには、カラムのセットを含めることはできません.そのため、個別のテーブルを追加する必要があります.
5.1値タイプのセットの使用
値タイプセットの登録
Member member = new Member();
// 임베디드 값 타입
member.setHomeAddress(new Address("ㄱ","ㄴ","ㄷ"));
// 기본 값 타입 컬렉션
member.getFavoriteFoods().add("r");
member.getFavoriteFoods().add("s");
// 임베디드 값 타입 컬렉션
member.getAddressHistory().add(new Address("1"));
member.getAddressHistory().add(new Address("2"));
em.persist(member);
値タイプのセットには、孤立オブジェクトを永続的に移行および除去する機能が必要です.値タイプセットの変更
Member member = em.find(Member.class, 1L);
// 임베디드 값 타입
member.setHomeAddress(new Address("ㄱ","ㄴ","ㄷ"));
// 기본 값 타입 컬렉션
Set<String> favoriteFoods = member.getFavoriteFoods();
favoriteFoods.remove(r); // String 타입을 수정할 수 없다.
favoriteFoods().add("s");
// 임베디드 값 타입 컬렉션
List<Address> addressHistory = member.getAddressHistory();
addressHistory.remove(new Address("1")); // 값 타입은 불변하므로 삭제 후 새로 등록한다.
addressHistory.add(new Address("2"));
5.2値タイプ集合の制限
値タイプのセットに保存された値は、別のテーブルに保存されます.これらの値を変更すると、データベース内の元のデータが見つかりにくくなります.
この問題を解決するために、JPA実施者が値タイプのセットを変更した場合
Reference
この問題について([JPA]9枚価格タイプ), 我々は、より多くの情報をここで見つけました https://velog.io/@offsujin/JPA-9장-값-타입テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol