1. 직접 할당
@Id만 사용한다.
✅예시
@Id
private String id;
2. 자동 생성
@GeneratedValue 애노테이션과 strategy 속성으로 GenerationType을 세팅해야한다.
타입 종류 | 설명 |
IDENTITY | 기본키를 자동으로 증가시킨다. |
SEQUENCE | DB 시퀀스를 사용하여 기본키를 생성한다. @SequenceGenerator를 사용하여 시퀀스를 정의해야한다. ex) Oracle, PostgreSQL, DB2, H2, MariaDB, SQL Server 사용가능 |
TABLE | 별도의 키 생성용 테이블을 사용하여 기본키 값을 생성한다. @TableGenerator를 사용하여 테이블을 정의해야한다. 모든 DB에 적용이 가능하다. |
AUTO | 방언(DB 문법)에 따라 자동 지정, 기본값이다. |
✔️ IDENTITY
- IDENTITY는 기본키 생성을 데이터베이스에 위임한다.
ex) MySQL, PostgreSQL, SQL Server, DB2에서 사용
- 예외적으로 em.persist() 시점에 즉시 INSERT SQL을 실행한다.
(commit시점에 insert 쿼리가 실행되지 않는다는 점!
그래서 한번에 모아서 insert를 할 수가 없다.)
- SEQUENCE를 지원하지 않는 DB에서는 SEQUENCE 타입을 쓸 수 없다.
이런 경우, IDENTITY를 사용한다.
✔️ SEQUENCE
- 시퀀스 오브젝트를 만든다.
- id 타입은 Long을 써야한다.
✔️TABLE
- 시퀀스를 지원하지 않는 DB에서 시퀀스와 비슷한 방식으로 기본 키를 생성할 수 있도록 한다.
- 단, 시퀀스보다 성능이 떨어진다.
1) @SequenceGenerator 사용법
- name: 시퀀스 생성기의 이름. @GeneratedValue 애노테이션의 generator 속성에서 참조한다.
- sequenceName: 실제 데이터베이스 시퀀스 이름.
- initialValue: 시퀀스의 초기 값.
- allocationSize: 시퀀스가 증가하는 단위. (기본값 50) (성능최적화에 사용된다.)
✅예시
package hellojpa;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "MEMBER_SEQ_GENERATOR")
private Long id;
@Column(name = "name", nullable = false)
private String username;
public Member() {
}
}
✅애플리케이션 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member member1 = new Member();
Member member2 = new Member();
Member member3 = new Member();
member1.setUsername("A");
member2.setUsername("B");
member3.setUsername("C");
em.persist(member1);
em.persist(member2);
em.persist(member3);
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
}
}
✅로그
Hibernate:
create sequence MEMBER_SEQ start with 1 increment by 1
Hibernate:
create table Member (
id bigint not null,
name varchar(255) not null,
primary key (id)
)
Hibernate:
select
next value for MEMBER_SEQ
Hibernate:
/* insert for
hellojpa.Member */insert
into
Member (name, id)
values
(?, ?)
✔️IDENTITY와 다르게 commit 시점에서 insert 쿼리에 실행된다.
(모아서 insert하는게 가능하다.)
✅실행 결과 확인
시퀀스 오브젝트가 생성됐다.
애플리케이션 실행부에서 id값을 세팅하지 않아도 ID컬럼을 기본키로 하여 순차적으로 세팅된다.
2) @TableGenerator 사용법
- name: 생성기 이름. @GeneratedValue 애노테이션의 generator 속성에서 참조한다.
- table: 키 값을 저장할 테이블 이름.
- pkColumnName: 시퀀스 이름을 저장할 컬럼 이름.
- valueColumnName: 다음 키 값을 저장할 컬럼 이름.
- pkColumnValue: 이 생성기에서 사용할 시퀀스 이름.
- initialValue: 초기 값.
- allocationSize: 증가 값. (기본값 50, 성능 최적화에 사용된다.)
✅예시
package hellojpa;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@TableGenerator(
name = "MEMBER_SEQ_GENERATOR", //generator 속성 참조
table = "MY_SEQUENCES", //키 값 저장할 테이블명
pkColumnValue = "MEMBER_SEQ", allocationSize = 1) //시퀀스 이름을 저장할 컬럼명
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "MEMBER_SEQ_GENERATOR")
private Long id;
@Column(name = "name", nullable = false)
private String username;
public Member() {
}
}
✅애플리케이션 실행부
package hellojpa;
import jakarta.persistence.*;
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try{
Member member1 = new Member();
member1.setUsername("C");
em.persist(member1);
tx.commit();
}catch (Exception e){
tx.rollback();
}finally {
em.close();
}
}
}
✅로그
Hibernate:
drop table if exists Member cascade
Hibernate:
drop table if exists MY_SEQUENCES cascade
Hibernate:
create table Member (
id bigint not null,
name varchar(255) not null,
primary key (id)
)
Hibernate:
create table MY_SEQUENCES (
next_val bigint,
sequence_name varchar(255) not null,
primary key (sequence_name)
)
Hibernate:
insert into MY_SEQUENCES(sequence_name, next_val) values ('MEMBER_SEQ',0)
Hibernate:
select
tbl.next_val
from
MY_SEQUENCES tbl
where
tbl.sequence_name=? for update
Hibernate:
update
MY_SEQUENCES
set
next_val=?
where
next_val=?
and sequence_name=?
Hibernate:
/* insert for
hellojpa.Member */insert
into
Member (name, id)
values
(?, ?)
시퀀스 테이블이 만들어지고 INSERT 쿼리가 실행된다.
✅실행 결과 확인
시퀀스 테이블이 생성됐다.
애플리케이션 실행부에서 id값을 따로 세팅해주지 않아도 ID값이 1로 저장됐다.
'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
JPA 기본 | 연관관계 매핑 기초 (0) | 2024.06.13 |
---|---|
H2 새로운 데이터베이스로 접속 오류 해결하기 (0) | 2024.06.10 |
JPA 기본 | 필드와 컬럼 매핑 | @Column, @Enumerated, @Temporal, @Lob (0) | 2024.06.10 |
JPA 기본 | 데이터베이스 스키마 자동 생성 옵션 (0) | 2024.06.10 |
JPA 기본 | @Entity (0) | 2024.06.10 |