728x90

엔티티 식별자 생성 방식

식별자 생성 방식

  • 직접 할당
    • @Id 설정 대상에 직접 값 설정
      • 사용자가 입력한 값, 규칙에 따라 생성한 값 등
      • 예) 이메일, 주문 번호
    • 저장하기 전에 생성자 할당, 보통 생성 시점에 전달
  • 식별 칼럼 방식
    • DB의 식별 칼럼에 매핑(예, MySQL 자동 증가 칼럼)
      • db가 식별자를 생성하므로 객체 생성 시에 식별 값을 설정하지 않음
    • 설정 방식
      • @GeneratedValue(strategy = Generation.Type.IDENTITY) 설정
    • Insert 쿼리를 실행해야 식별자를 알 수 있음
      • EntityManager#persist() 호출 시점에 Insert 쿼리 실행
      • persist() 실행할 때 객체에 식별자 값 할당됨
  • 시퀀스 사용 방식
    • 시퀀스 사용해서 식별자 생성
      • 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

  1. 엔티티가 아닌 타입을 한 개 이상의 필드와 매핑할 때 사용
    1. 예 : Adress, Money 등 매핑
  2. 엔티티의 한 속성으로 @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 

 

728x90

+ Recent posts