기본 키 매핑

gotcha!!·2023년 9월 8일
0

JPA

목록 보기
8/16

기본키 매핑

  • @Id
  • @GeneratedValue

@Id

ID를 직접 만들어서 할당하는 것

@Id, @GeneratedValue

자동 생성은 @Id와 @GeneratedValue를 함께 사용한다.

  • IDENTITY: 데이터베이스에 위임, MYSQL
  • SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE
    @SequenceGenerator 필요
  • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
    @TableGenerator 필요
  • AUTO: 방언에 따라 자동 지정, 기본값

IDENTITY

• 기본 키 생성을 데이터베이스에 위임
• 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용
 (예: MySQL의 AUTO INCREMENT)
• JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행
• AUTO
INCREMENT는 데이터베이스에 INSERT SQL을 실행
한 이후에 ID 값을 알 수 있음
• IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL 실행 하고 DB에서 식별자를 조회

IDENTITY 전략은 영속성 컨텍스트(1차 캐시)에 값을 넣을 때는 PK 값이 꼭 필요한데, 그 PK 값을 가져오기 위해서 미리 em.persist 시점에 insert sql을 실행하고 DB에서 식별자를 가져와 1차 캐시에 넣는다.

@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

SEQUENCE

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예: 오라클 시퀀스)
  • 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용

SEQUENCE 전략은 IDENTITY와 똑같이, 영속성 컨텍스트에 PK값을 넣기
위해서 em.persist() 시점에
"call next value for 시퀀스명" 을 통해서 PK값을 생성하고 영속성 컨텍스트에 식별자를 전달해준다.
즉 INSERT SQL문을 모았다가 한 번에 보내는 방법이 가능하다. 그러나 IDENTITY는 INSERT SQL을 하나씩 날려야하므로 불가능하다.

@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;

TABLE

  • 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내 내는 전략
  • 모든 데이터베이스에 적용 가능
  • 그러나 테이블을 직접 사용하다 보니 성능 이슈가 발생한다.
@Entity
@TableGenerator(
name = "MEMBER_SEQ_GENERATOR",
table = "MY_SEQUENCES",
pkColumnValue = “MEMBER_SEQ", allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "MEMBER_SEQ_GENERATOR")
private Long id;

create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key ( sequence_name )
)
쿼리가 생기고, 따로 테이블이 생긴다.

참고

profile
ha lee :)

0개의 댓글