Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- db
- Servlet
- jpa
- 스프링
- Thymeleaf
- java
- Spring Boot
- SpringBoot
- Greedy
- Exception
- 인프런
- kotlin
- JPQL
- 김영한
- 알고리즘
- 그리디
- pointcut
- QueryDSL
- transaction
- 자바
- JDBC
- Android
- http
- springdatajpa
- AOP
- 백준
- 스프링 핵심 기능
- spring
- Proxy
- 스프링 핵심 원리
Archives
- Today
- Total
개발자되기 프로젝트
기본 키(PK) 매핑 본문
1. PK 매핑 방법
- 직접 할당 : @Id만 사용
- 자동 생성 : @GeneratedValue
- IDENTITY: 데이터베이스에 위임, MYSQL
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
- SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE --> @SequenceGenerator 필요
- TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용 --> @TableGenerator 필요
- AUTO: 방언에 따라 자동 지정, 기본값
2. IDENTITY
- 기본 키 생성을 DB에 위임 : 너가 알잘딱해
- MySQL, PstgreSQL, SQL Server, DB2에서 사용
- JPA는 보통 transaction commit 시점에 INSERT SQL 실행
- AUTO_INCREMENT는 DB에 INSERT SQL을 실행한 이후에 ID값을 알 수 있음
- IDENTITY 전락은 em.persist()시점에 즉시 INSERT SQL 실행하고 DB에서 식별자 조회함.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
- IDENTITY 전략으로 생성된 것을 확인할 수 있다.
Hibernate:
create table Member (
id bigint generated by default as identity,
name varchar(255),
primary key (id)
)
- 이 상태에서 방언을 바꿔보면...?(MySQL로 변경)
- auto_increment로 생성됨. Hibernate: create table Member ( id bigint not null auto_increment, name varchar(255), primary key (id) ) engine=MyISAM
- IDENTITY 전략은 개발자가 id를 넣지 않고 DB에 insert를 함.
- id가 null로 INSERT SQL이 날라가면 DB에서 값을 세팅해줌.
- 즉 DB에 데이터가 들어가야 ID를 알 수 있음.
- 어? 근데 영속성 컨텍스트에서 관리되려면...PK가 필요한데...?PERSIST한다고 DB에 들어가는것도 아닌데..?
- 그래서..IDENTITY 전략에 한해서만, em.psersist(entity) 호출 하자마자 DB에 바로 SQL 날려버림....!!
- 그리고 id값을 return 받기 때문에 persist 시점에 id값을 알 수 있게 된다.
- 흠..지연쓰기 이점이 없는데????->단점!
3. SEQUENCE
- DB에 있는 sequence object를 통해 값을 생성함.
- 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예: 오라클 시퀀스)
- 따라서 SEQUENCE 전략은 hibernate_sequence를 생성한다.
- 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate:
call next value for hibernate_sequence
- 만약 테이블 마나 시퀀스 따로 관리하고 싶으면
- @SequenceGenerator, @GeneratedValue(generator = "")
@Entity
@SequenceGenerator(name = "member_seq_generator", sequenceName = "member_seq")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq")
private Long id;
Hibernate: create sequence member_seq start with 1 increment by 50
Hibernate:
call next value for member_seq
- @SequenceGenerator
- 주의 : allocationSize의 기본값= 50
속성 | 설명 | 기본값 |
name | 식별자 생성기 이름. | 필수 |
sequenceName | 데이터베이스에 등록되는 시퀀스 이름 | hibernate_sequence |
initialValue | DDL 생성 시에만 사용됨. 시퀀스 DDL을 생성할 때 처음 1 시작하는 수를 지정한다. | 1 |
allocationSize | 시퀀스 한 번 호출에 증가하는 수 (성능 최적화에 사용. 데이터 베이스 시퀀스 값이 하나 씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 함 |
50 |
catalog, schema | 데이터베이스 catalog, schema이름 |
- em.persist(entity)를 할 때 영속성 컨텍스트에 들어가야 하는데, PK가 필요해!
- 그럼 persist전에 시퀀스를 먼저 가져와서 id값을 넣고 영속성 컨텍스트에 올라감. 이 시점에 SQL은 안날라감
- SQL은 commit 시점에 날라감.
- 즉 한방에 SQL 날리기 가능
- 흠 근데 ID 가져올라고 계속 네트워크타니 성능 문제 없을까...?
3-1) allocationSize : 기본값 50
- 매번 DB에서 받아오면 성능문제 있으니 미리 DB에 50개 미리 올려둠.
메모리에서 하나씩 갯수에 맞춰 id소모. 50개 다차면 DB에 다시 50개 올려둠. - 여러 개를 PERSIST하는 경우 처음 두 번만 call next value for DB_SEQ를 호출하고
나머지는 메모리에서 호출한다. - 객체 개수가 쌓여서 id가 51이 되면 call next value for DB_SEQ 호출함.
- 보통 50~100정도가 적당.
- 값을 미리 올려두는 방식이기 때문에 서버가 여러개여도 미리 확보를 해두기 때문에 문제 없음.
- ID 값을 call next value 를 호출할 때 받기 때문에 어디까지 쓸 수 있는지 알고있음.
4. TABLE 전략
- 키 생성 전용 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;
- log
create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key ( sequence_name )
)
- 운영에서 쓰기 부담스러움....
5. 권장하는 식별자 전략
- 기본 키 제약 조건은 : null이 아니고, 유일하고, 변하면 안된다.(어려움..)
- 정~~~~~~~말 나중까지 변하면 안됨.
- 미래까지 이 조건을 만족하는 자연지를 찾기 어려움..(주민번호, 전화번호 등등)
- 따라서 비즈니스와 전~혀 상관없는 대리키(대체키)를 사용하자.
- 주민번호도 안됨!
- 권장 : Long형(10억 넘어도되게) + 대체키 + 키 생성 전략 사용.
'인프런 > [인프런] 자바ORM 표준 JPA 프로그래밍' 카테고리의 다른 글
단방향 연관관계 (0) | 2021.08.09 |
---|---|
예제 : 요구사항 분석과 기본 매핑. (0) | 2021.08.09 |
필드와 컬럼 매핑 (0) | 2021.08.09 |
데이터베이스 스키마 자동 생성, DDL 주의사항 (0) | 2021.08.09 |
객체와 테이블 매핑 (0) | 2021.08.08 |
Comments