Dev/JPA
RS) 기본키 매핑
Okdol-Min
2022. 2. 3. 22:44
기본 키 매핑 어노테이션
- @Id (직접 할당)
- 직접 할당하는 경우 @Id만 사용
- @GeneratedValue (자동 생성)
- GeneratedValue 전략
- IDENTITY : 데이터베이스에 위임, MYSQL
- "나는 모르겠고, DB야 니가 알아서 해줘" 라는 의미의 전략
- ID 값을 알 수 있는 시점이 DB에 값이 들어가야만 알 수 있다.
- 영속성 컨텍스트에서 관리하려면(PK = ID)값이 있어야하는데, 이점이 문제가 된다.
- 그래서 원래는 트랜잭션이 커밋되었을 때 INSERT 쿼리가 디비로 날라가야하는데 IDENTITY 타입의 전략에서만 예외적으로 em.persist 하는 순간 INSERT 쿼리가 날라가게 된다.
public class Member { @Id // GeneratedValue 전략이 IDENTITY 일 경우에만 예외적으로 @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; try{ Member member = new Member(); member.setUsername("C"); System.out.println("==================="); // em.persist 하는 순간 INSERT문이 날라간다. // 영속성 컨텍스트에서 관리를 하려면 PK가 필요한데, IDENTITY 전략은 DB에 값이 들어가야만 // ID값을 확인할 수 있기 때문에.. em.persist(member); System.out.println("==================="); /* 실행결과 */ =================== Hibernate: /* insert hellojpa.Member */ insert into Member (id, age, description, roleType, testLocalDate, testLocalDateTime, name) values (null, ?, ?, ?, ?, ?, ?) ===================
- SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
- @SequenceGenerator 사용
- Integer나 Int형의 타입은 사용하기 애매하다 → Long 타입을 사용하는 것을 추천
@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;
- SEQUENCE 전략을 사용하는 것도 시퀀스를 사용하는 것이기 때문에 DB에 가봐야 값을 알 수 있다.
- em.persist 할때 영속성 컨텍스트에 넣어줘야하는데 그럴경우 PK가 필요하다.
- 그래서 JPA는 em.persist 할 때 먼저 SEQUENCE 전략인 것을 확인하고 디비에서 시퀀스 값을 먼저 불러온다.
try{ Member member = new Member(); member.setUsername("C"); System.out.println("==================="); em.persist(member); System.out.println("member Id = "+ member.getId()); System.out.println("==================="); tx.commit(); // 커밋하는 순간 디비에 날라간다. /* 실행 결과 */ =================== Hibernate: // 영속성 컨텍스트에 넣기 위해 JPA는 전략이 시퀀스인 것을 확인하고 DB에서 시퀀스를 먼저 부른다. call next value for MEMBER_SEQ member Id = 1 =================== Hibernate: /* insert hellojpa.Member */ insert into Member (age, description, roleType, testLocalDate, testLocalDateTime, name, id) values (?, ?, ?, ?, ?, ?, ?)
- SEQUENCE 전략을 사용하는 것도 시퀀스를 사용하는 것이기 때문에 DB에 가봐야 값을 알 수 있다.
- TABLE : 키 생성용 테이블 사용, 모든 데이터베이스에서 시퀀스를 흉내내는 전략
- 모든 데이터베이스에서 적용가능 하지만, 테이블을 직접 사용하다 보니까 성능이 안 좋다.
- TableGenerator 필요
- AUTO : 바언에 따라 자동 지정
- 설정하지 않으면 기본 값으로 AUTO로 설정 된다.
- IDENTITY : 데이터베이스에 위임, MYSQL
- GeneratedValue 전략
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
권장하는 식별자 전략
- 기본 키 제약 조건 : null 아님, 유일, 변하면 안된다.
- 미래까지 조건을 만족하는 자연키를 찾기 어렵다. 대리키(대체키)를 사용하자
- 주민등록번호같은 경우도 기본 키로 적절하지 않다.
- 권장방법 : Long형 + 대체키 + 키 생성전략 사용