본 포스팅은 인프런 - 자바 ORM 표준 JPA 프로그래밍 (기본편) 을 강의를 바탕으로 공부하고 정리한 글입니다.
엔티티 매핑하기
- 객체와 테이블 매핑 : @Entity, @Table
- 필드와 컬럼 매핑 : @Column
- 기본 키 매핑 : @Id
- 연관관계 매핑 : @ManyToOne, @JoinColumn
기본 키 매핑
@Id | 직접 할당 | ||
@GeneratedValue | 자동 생성 | IDENTITY | • 데이터베이스에 위임 • MYSQL에서 사용 |
SEQUENCE | • 데이터베이스 시퀀스 오브젝트 사용 • ORACLE에서 사용 • @SequenceGenerator 필요 |
||
TABLE | • 키 생성용 테이블 사용 • 모든 DB에서 사용 • @TableGenerator 필요 |
||
AUTO | • 방언에 따라 자동 지정 • 기본값 |
IDENTITY 전략
- 기본 키 생성을 데이터베이스에 위임하는 전략
- 주로 MYSQL, PostgreSQL, SQL Sever, DB2에서 사용
- IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL을 실행해 DB에서 식별자를 조회한다.
- JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL을 실행한다.
MYSQL의 AUTO_INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있기 때문에
IDENTITY 전략 시 트랜잭션 커밋 시점이 아닌 em.persist() 시점에 INSERT 쿼리를 날린다. - 따라서 IDENTITY 전략에서는 SQL을 모아서 전송하는 것이 불가능하다는 단점이 있다.
- JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL을 실행한다.
더보기
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}
Hibernate:
create table Member (
id bigint generated by default as identity,
name varchar(255),
primary key (id)
)
SEQUENCE 전략
- 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다.
- 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용
💡 @SequenceGenerator의 속성
속성 | 설명 | 기본값 |
name | 식별자 생성기 이름 | 필수 |
sequenceName | 데이터베이스에 등록되어 있는 시퀀스 이름 | hibernate_sequence |
initalValue | DDL 생성 시에만 사용 시퀀스 DDL을 생성할 때 처음 1 시작하는 수를 지정 |
1 |
allocationSize | 시퀀스 한번 호출에 증가하는 수 (성능 최적화에 사용됨) 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 함 |
50 |
catalog, schema | 데이터베이스 catalog, schema 이름 |
더보기
@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;
}
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate:
call next value for hibernate_sequence
TABLE 전략
- 키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략
- 장점 : 모든 데이터베이스에 적용이 가능하다.
- 단점 : 테이블을 직접 사용하다 보니 성능이 떨어진다.
💡 @SequenceGenerator의 속성
속성 | 설명 |
name | 식별자 생성기 이름 |
table | 키생성 테이블명 |
pkColumnName | 시퀀스 컬럼명 |
valueColumnNa | 시퀀스 값 컬럼명 |
pkColumnValue | 키로 사용할 값 이름 |
initialValue | 초기 값, 마지막으로 생성된 값이 기준 |
allocationSize | 시퀀스 한번 호출에 증가하는 수 (성능 최적화에 사용) |
catalog, schema | 데이터베이스 catalog, schema 이름 |
uniqueConstraint (DDL) | 유니크 제약 조건을 지정할 수 있다. |
더보기
@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;
}
Hibernate:
create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key ( sequence_name )
)
권장하는 식별자 전략은?
- 데이터베이스의 기본 키 제약 조건을 생각해보자.
- null이면 안됨
- 유일해야 함
- 변하면 안됨
- 미래까지 위 조건을 만족하는 자연키(ex. 주민번호)는 찾기 어렵다.
- 따라서 대리키(대체키)를 사용하는 것이 좋다.
결론적으로, 타입은 Long형(10억 넘어도 동작해야하기 때문) + 대체키(예를 들어 sequence를 사용하거나 uuid) + 키 생성 전략을 조합하여 사용하는 것을 권장한다!
'🌱 Spring > JPA' 카테고리의 다른 글
[JPA] 연관관계 매핑(3) - 다중성 (ManyToOne, ManyToOne, OneToOne, ManyToMany) (1) | 2022.10.11 |
---|---|
[JPA] 연관관계 매핑(2) : 양방향 매핑 (0) | 2022.10.06 |
[JPA] 연관관계 매핑(1) : 단방향 매핑 (0) | 2022.10.06 |
[JPA] 데이터베이스 스키마 자동 생성 : DDL AUTO (0) | 2022.09.30 |
[JPA] 엔티티 매핑(1) - 객체와 테이블, 필드와 컬럼 매핑 (0) | 2022.09.30 |
[JPA] 영속성 관리 (0) | 2022.09.29 |
[JPA] JPQL : 객체 지향 쿼리 언어 (0) | 2022.09.29 |
[JPA] JPA 왜 사용할까? (0) | 2022.09.22 |