HyeLog
[김영한_자바 ORM 표준 JPA 프로그래밍 - 기본편] 3. 엔티티 매핑(2) 본문
※ 이번 실습 때 내가 설치한 H2 데이터베이스 버전 때문에 @GeneratedValue 가 제대로 작동하지 않아서, H2를 아예 삭제하고 1.4.200 버전으로 재설치했다. 재설치할 때 기존 H2로 인해 만들어진 파일들을 꼭 삭제해야 한다.
(참고: https://www.inflearn.com/questions/429626 , https://www.inflearn.com/questions/459129)
👩💻기본키(PK) 매핑
- 직접 할당 → @id
- 자동 생성 → @GeneratedValue
@GeneratedValue는 데이터베이스에서 PK가 자동으로 생성되게 하고 싶을 때 사용한다.
GenerationType은 3가지(TABLE / IDENTITY / SEQUENCE)가 있다. 디폴트는 AUTO로, 3가지 중 데이터베이스 방언에 맞는 것으로 자동 설정된다.
IDENTITY
IDENTITY는 MySQL의 AUTO_INCREMENT 라고 생각하면 된다.
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false)
private String username;
// JPA 는 기본 생성자가 필수.
public Member() {
}
// getter, setter 함수들
}
아래와 같이 username만 set해주면, id는 자동으로 증가해서 INSERT된 것을 볼 수 있다.
Member member = new Member();
member.setUsername("C");
em.persist(member);
transaction.commit();

SEQUENCE
SEQUENCE는 Oracle에서 사용한다. Table마다 시퀀스를 따로 관리해야 하기 때문에 @SequenceGenerator로 각각 이름을 지정한다.
⭐주의할 점은 allocationSize = 1 설정을 해주어야 1씩 증가한다. 설정하지 않으면, 50이 디폴트값이기 때문에 1번째 데이터의 id가 1일 때 2번째 데이터의 id는 52가 된다. allocationSize를 50~100으로 크게 설정해서 성능 최적화를 할 수도 있다.
@Entity
@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR", sequenceName = "MEMBER_SEQ", initialValue = 1, allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
// 생략
}
권장하는 기본키(PK) 매핑 전략
Long형 + 대체키(비즈니스와 관련 없는 값. 주민등록번호도 적절하지 않음) + 키 생성전략(Ex. UUID) 사용
👩💻 실전 예제
간단한 쇼핑몰을 예로 들어보자. DB의 Table은 다음과 같다.
(회원 : 주문 = 1 : N , 주문 : 상품 = N : M 관계이다. )
- MEMBER 테이블
- ORDERS 테이블 (MEMBER_ID를 FK로 가짐)
- ITEM 테이블
- ORDER_ITEM 테이블
이제 엔티티를 설계해야 한다. 만약, 엔티티를 DB 테이블과 완전히 똑같이 설계해서, Order 클래스(엔티티)의 필드에 MemberId를 넣으면 어떻게 될까?
@Entity
@Table(name = "ORDERS")
public class Order {
@Column(name = "MEMBER_ID")
private Long memberId;
// 다른 필드는 생략
}
'주문을 한 회원 정보'를 가져오려면, 아래와 같이 memberId를 가져와서 또 그것으로 회원을 조회해야 한다.
Order order = em.find(Order.class, 1L);
Long memberId = order.getMemberId();
Member member = em.find(Member.class, memberId);
이렇게 데이터 중심 설계를 하는 것은 좋지 않다. 객체 중심적인 설계로 바꾸어보자.
@Entity
@Table(name = "ORDERS")
public class Order {
private Member member;
// 다른 필드는 생략
}
이렇게 Member 객체 자체를 필드로 가지게 되면, 문제가 해결된다.
'웹 개발 > Spring Boot' 카테고리의 다른 글
[김영한_자바 ORM 표준 JPA 프로그래밍 - 기본편] 5. 다양한 연관관계 매핑 (0) | 2022.06.12 |
---|---|
[김영한_자바 ORM 표준 JPA 프로그래밍 - 기본편] 4. 연관관계 매핑 기초 (0) | 2022.06.11 |
[김영한_자바 ORM 표준 JPA 프로그래밍 - 기본편] 3. 엔티티 매핑(1) (0) | 2022.06.08 |
[김영한_자바 ORM 표준 JPA 프로그래밍 - 기본편] 2. 영속성 관리 (0) | 2022.06.08 |
[김영한_자바 ORM 표준 JPA 프로그래밍 - 기본편] 1. JPA 시작하기(2) (0) | 2022.06.07 |