엔티티 식별자 생성 방식
식별자 생성 방식
- 직접 할당
- @Id 설정 대상에 직접 값 설정
- 사용자가 입력한 값, 규칙에 따라 생성한 값 등
- 예) 이메일, 주문 번호
- 저장하기 전에 생성자 할당, 보통 생성 시점에 전달
- @Id 설정 대상에 직접 값 설정
- 식별 칼럼 방식
- DB의 식별 칼럼에 매핑(예, MySQL 자동 증가 칼럼)
- db가 식별자를 생성하므로 객체 생성 시에 식별 값을 설정하지 않음
- 설정 방식
- @GeneratedValue(strategy = Generation.Type.IDENTITY) 설정
- Insert 쿼리를 실행해야 식별자를 알 수 있음
- EntityManager#persist() 호출 시점에 Insert 쿼리 실행
- persist() 실행할 때 객체에 식별자 값 할당됨
- DB의 식별 칼럼에 매핑(예, MySQL 자동 증가 칼럼)
- 시퀀스 사용 방식
- 시퀀스 사용해서 식별자 생성
- JPA가 식별자 생성 처리 → 객체 생성 시에 식별 값을 설정하지 않음
- 설정 방식
- @SequenceGenerator로 시퀀스 생성기 설정
- @GeneratedValue로 generator로 시퀀스 생성기 지정
- EntityManager#persist() 호출 시점에 시퀀스 사용
- persist() 실행할 때 객체에 식별자 값 할당됨
- Insert 쿼리는 실행하지 않음
- 시퀀스 사용해서 식별자 생성
- 테이블 사용 방식
- 테이블을 시퀀스처럼 사용
- 테이블에 엔티티를 위한 키를 보관
- 해당 테이블을 이용해서 다음 식별자 생성
- 설정 방식
- @TableGenerator로 테이블 생성기 설정
- @GeneratedValue의 generator로 테이블 생성기 지정
- EntityManager#persist() 호출 시점에 테이블 사용
- persist() 할 때 테이블을 이용해서 식별자 구하고 이를 엔티티에 할당
- Insert 쿼리는 실행하지 않음
- 식별자를 생성할 때 사용할 때 테이블 구조
- 엔티티 이름 칼럼
- 식별자 보관 칼럼
- 테이블을 시퀀스처럼 사용
https://www.youtube.com/watch?v=Xw9uTs72SVo&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=5
@Embeddable
- 엔티티가 아닌 타입을 한 개 이상의 필드와 매핑할 때 사용
- 예 : Adress, Money 등 매핑
- 엔티티의 한 속성으로 @Embeddable 적용 타입 사용
@Embeddable
public class Adress {
@Column(name = "addr1")
private String address1;
@Column(name = "addr2")
private String address2;
@Column(name = "zipcode")
private String zipcode;
protected Address() {
}
... 생성자, getter 생략
@Entitiy
@Table(name = "hotel_info")
public class Hotel {
@Id
@Column(name = "hotel_id")
private String id;
....
@Embedded
private Adress adress;
같은 @Embeddable 타입 필드가 두 개면?
문제점
@Entity
public class Employee {
@Id
private String id;
@Embedded
private Address homeAddress;
@Embedded
private Address workAddress;
}
서로 같은 컬럼에 매핑이되어서 엔티티메니저팩토리를 초기화할 때 에러가 난다.
해결법
@Entity
public class Employee {
@Id
private String id;
@Embedded
private Address homeAddress;
@AttributeOverrides({
@AttributeOverride(name = "address1", column = @Column(name = "waddr1")),
@AttributeOverride(name = "address2", column = @Column(name = "waddr2")),
@AttributeOverride(name = "zipcode", column = @Column(name = "wzipcode"))
})
@Embedded
private Address workAddress;
}
정리
- @Embeddable을 사용하면 모델을 더 잘 표현할 수 있음
- 개별 속성을 모아서 이해 → 타입으로 더 쉽게 이해
- (addr1, addr2, zipcode)를 모아서 ‘이게 주소구나’ → ‘주소’네
https://www.youtube.com/watch?v=WtS5IszIueA&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=6
@Embeddable 다른 테이블에 매핑하기
다른 테이블에 값을 저장할 때
- @SecondaryTable + 테이블명
@Embeddable
public class Intro {
@Column(table = "writer_intro", name = "content_type")
private String contentType;
@Column(table = "writer_intro")
private String content;
...
}
@Entity
@SecondaryTable(name = "writer_intro",
pkJoinColumns = @PrimaryKeyJoinColumn(
name = "writer_id", // writer_intro 테이블 칼럼
referencedColumnName = "id" // writer 테이블 칼럼
)
)
public class Writer {
...
@Embedded
private Intro intro;
}
- @SecondaryTable + @AttributeOverride
@Embeddable
public class Address {
@Column(name = "addr1")
private String address1;
@Column(name = "addr2")
private String address2;
@Column(name = "zipcode")
private String zipcode;
}
@Entity
@SecondaryTables({
@SecondaryTable(name = "writer_address",
pkJoinColumns = @PrimaryKeyJoinColumn(
name = "writer_id",
referencedColumnName = "id"
),
...
})
public class Writer {
....
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "address1",
column = @Column(table= "writer_address", name = "addr1")),
@AttributeOverride(name = "address2",
column = @Column(able= "writer_address", name = "addr2")),
@AttributeOverride(name = "zipcode",
column = @Column(nable= "writer_address"))
})
private Address address;
정리
- @SecondaryTable
- 다른 테이블에 저장된 데이터를 @Embeddable로 매핑 가능
- 다른 테이블에 저장된 데이터가 개념적으로 밸류(값)일 때 사용
- 1 - 1 관계인 두 테이블을 매핑할 때 종종 출현
https://www.youtube.com/watch?v=3_sdQGfL2Lg&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=7
값 컬렉션 Set 매핑
- 단순 값 Set 매핑
@Entity
@Table(name = "role")
public class Role {
@Id
private String id;
private String name;
@ElementCollection
@CollectionTable(
name = "role_perm",
joinColumns = @JoinColumn(name = "role_id")
)
@Column(name = "perm")
private Set<String> permission = new HashSet<>();
정리
- 컬렉션 테이블을 이용한 값 set 매핑
- @ElementCollection과 @CollectionTable이면 끝
https://www.youtube.com/watch?v=lQ4-kVeHVGk&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=8
값 컬렉션 List 매핑
- 단순 값 List 매핑
@Entity
@Table(name = "question")
public class Question {
@Id
private String id;
private String text;
@ElementCollection
@CollectionTable(
name = "question_choice",
joinColumns = JoinColumn(name = "question_id")
)
@OrderColumn(name = "idx")
@Column(name = "text")
private List<String> choices;
정리
- 컬렉션 테이블을 이용한 값 List 매핑
- @ElementCollection과 @CollectionTable, @OrderColumn이면 끝
https://www.youtube.com/watch?v=Wq4B5RpIeAY&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=9
값 컬렉션 Map 매핑
- 앞에 Set하고 동일
@Entity
@Table(name = "doc")
public class Role {
@Id
private String id;
private String name;
private String content;
@ElementCollection
@CollectionTable(
name = "doc_prop",
joinColumns = @JoinColumn(name = "doc_id")
)
@MapKeyColumn(name = "name")
@Column(name = "value")
private Map<String, String> props = new HashMap<>();
정리
- 컬렉션 테이블을 이용한 값 Map 매핑
- @ElementCollection과 @CollectionTable, @MapKeyColumn이면 끝
https://www.youtube.com/watch?v=CPIgicoqLnM&list=PLwouWTPuIjUi9Sih9mEci4Rqhz1VqiQXX&index=10
'개발 > JPA' 카테고리의 다른 글
JPA 기초) 2. 코드 구조 & 영속 컨텍스트, 엔티티 CRUD 처리, 엔티티 매핑 설정 (0) | 2022.08.23 |
---|---|
JPA 기초) 1.일단 해보기 (0) | 2022.08.23 |