JPA에서 기본키를 어떻게 매핑할 수 있는지 알아보겠다
먼저, 엔티티에서 기본키를 매핑하려면
기본키에 해당하는 필드 위에 @Id 애너테이션을 붙이면 된다
@Entity
public class Member{
@Id
public Long id;
}
그리고 기본키 타입이 정수형일 경우
Insert시 기본키 값이 자동으로 증가되게 하려면
@GeneratedValue라는 애너테이션을 기본키에 해당하는 필드 위에 붙이면 된다
@Entity
public class Member{
@Id
@GerneratedValue(strategy=GenerationType.AUTO)
public Long id;
}
@GeneratedValue에는 기본키값을 증가시키는 여러 전략들이 존재한다
@GeneratedValue 전략
- GenerationType.AUTO - DBMS의 방언에 따라 설정(기본값)
@Entity
public class Member{
@Id
@GerneratedValue(strategy=GenerationType.AUTO)
public Long id;
}
- GenerationType.TABLE - 기본키값을 관리하는 테이블을 만들어서 기본키값을 가져옴, @TableGenerator필요, 모든 DBMS에 적용가능
/* JPA에서 생성해주는 기본 Sequence 테이블을 이용 */
// 다른 테이블과 Sequence 테이블을 혼용할 수 있으니 주의
@Entity
public class Member{
@Id
@GerneratedValue(strategy=GenerationType.TABLE)
public Long id;
}
/* 직접 생성한 Sequence 테이블을 이용 */
@Entity
@TableGenerator(
name="MEMBER_SEQ_GENERATOR", //TableGenerator명
table = "MEMBER_SEQS", //시퀀스 테이블명
pkColumnName = "MEMBER_SEQ", //시퀀스 컬럼명
initialValue = 1, //시작값
allocationSize = 50 //매 호출 시마다 가져올 시퀀스 값의 크기
)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
private Long Id;
}
GenerationType.TABLE의 경우에는 DBMS에서 제공해주는 Sequence나 AUTO_INCREMENT보다 성능이 좋지 않으므로 비추
-> 아래를 보면 기본키를 가져오는 쿼리 외에도 다음 값으로 증가시키는 Update 쿼리가 날라가는 걸 볼 수 있다
(성능저하의 원인)
시퀀스 테이블에 Lock이 걸릴 수 있다(Update 시)
/* 기본키값을 가져오는 쿼리 */
Hibernate:
select
tbl.next_val
from
MEMBER_SEQS tbl
where
tbl.MEMBER_SEQ=? for update
/* 다음 기본키값으로 업데이트 하는 쿼리 */
Hibernate:
update
MEMBER_SEQS
set
next_val=?
where
next_val=?
and MEMBER_SEQ=?
/* 가져온 기본키값으로 데이터를 Insert하는 쿼리 */
Hibernate:
/* insert org.example.domain.Member
*/ insert
into
Member
(age, gender, name, Id)
values
(?, ?, ?, ?)
- GenerationType.SEQUENCE - 오라클용, 시퀀스를 이용하여 기본키값을 가져옴, @SequenceGenerator 필요
/* JPA에서 생성해주는 시퀀스 사용 */
//다른 테이블과 시퀀스를 같이 쓰게 될 수도 있으니 주의
@Entity
public class Member{
@Id
@GerneratedValue(strategy=GenerationType.SEQUENCE)
public Long id;
}
/* 직접 생성한 시퀀스 사용 */
@Entity
@SequenceGenerator(
name="MEMBER_SEQ_GENERATOR", //SequenceGenerator 이름
sequenceName = "MEMBER_SEQ", //시퀀스 이름
initialValue = 1, //시퀀스 시작값
allocationSize = 1 //매 호출 시마다 가져올 시퀀스 값의 크기
)
public class Member{
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE, //GeneratedValue 전략
generator = "MEMBER_SEQ_GENERATOR" //사용할 SequenceGenerator 이름
)
public Long id;
}
- GenerationType.IDENTITY - MySQL용, AUTO_INCREMENT를 이용하여 기본키값을 가져옴
@Entity
public class Member{
@Id
@GerneratedValue(strategy=GenerationType.INDENTITY)
public Long id;
}
IDENTITY(AUTO_INCREMENT) 전략의 경우, PK값을 데이터를 Insert 하기 전까지 알 수 없다
(데이터를 Insert 할 때 PK값이 결정되기 때문이다)
그래서, JPA 내부적으로 영속성 컨텍스트에 PK값을 저장하기 위해
Insert 후 PK값을 Select하여 가져온다
위와 같은 이유로 IDENTITY 전략에서는 쿼리를 모아서 보낼 수 없다
persist 실행 후 바로 Insert 쿼리가 날라간다
'Spring > JPA' 카테고리의 다른 글
연관관계 - 양방향 연관관계(기본 컨셉) (0) | 2023.03.07 |
---|---|
연관관계 - 단방향 연관관계 (0) | 2023.02.28 |
환경세팅 (0) | 2023.02.24 |
Entity-Table 매핑 - 필드 매핑(@Transient) (0) | 2023.02.23 |
Entity-Table 매핑 - 필드 매핑(@Lob) (0) | 2023.02.23 |
댓글