본문 바로가기
Data Base/JPA

[JPA] : 기본 키 매핑

by 오주현 2022. 4. 5.
반응형
  • 키본 키를 매핑하는 방법은 직접 할당과 자동 생성이 있다.
    • 직접 할당은 @Id를 사용하면 된다.
    • 자동 생성은 @GeneratedValue 를 사용하면 된다.
      • 옵션
        • AUTO : 방언에 따라 자동 지정, 요즘엔 또 다를 수도 있어서 보고 사용해야 한다.
        • IDENTITY : 데이터베이스 위임. MYSQL
          • 기본키 생성을 데이터베이스에 위임한다.
        • SEQUENCE : 데이터베이스 시퀸스 오브젝트 사용, ORACLE
        • TABLE : 키 생성용 테이블 사용, 모든 DB에서 사용한다.
  • @SequenceGenerator
@Entity //JPA가 관리하는 객체고 데이터베이스 테이블과 매핑해서 사용하는구나! 하고 알면 된다.
//@Table(name = "MBR") //데이터베이스 MBR 테이블이랑 매핑된다. 즉, 매핑 할 때 테이블 명을 바꾼다.
@SequenceGenerator(name = "member_seq_generator", sequenceName = "member_seq")
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq_generator")
    private Long id;
  • TABLE 전략 매핑
@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;
  • 운영에서는 사용하기 부담스럽다.
  • TableGenerator 속성에도 여러가지가 있으나 테이블 전략 자체를 잘 사용하진 않는다.
  • 권장하는 식별자 전략
    • 기본 키 제약 조건을 생각해 봐야한다.
      • null 아님, 유일, 변하면 안된다.(먼 미래까지 변하면 안 됨. 이게 제일 어려움)
        • 미래까지 이 조건을 만족하는 자연키(주민번호, 전화번호 등)를 찾기 어렵다. → 대체키(대체키)(비즈니스와 상관이 전혀 없는 것)를 사용하는 게 좋다.
      • 주민번호도 기본 키로 적절하지 않다.
      • 권장은 Long형 + 대체키 + 키 생성전략 사용
        • 비즈니스를 키로 가져오는 것을 절대 권장하지 않는다.
  • IDENTITY 전략
    • IDENTITY의 전략은 id에 값을 넣으면 안된다.
    • insert를 하고 값이 들어가야 한다.
    • DB에 값이 들어가야 id값을 알 수 있다.
    • commit을 하기 전에 em.persist 할 때 쿼리가 실행되는 특징을 가지고 있다.
      • 디비가 생성하고 생성한 값을 가지고 온다.
  • @Entity //JPA가 관리하는 객체고 데이터베이스 테이블과 매핑해서 사용하는구나! 하고 알면 된다. //@Table(name = "MBR") //데이터베이스 MBR 테이블이랑 매핑된다. 즉, 매핑 할 때 테이블 명을 바꾼다. public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
  • allocationSize
@SequenceGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        sequenceName = "MEMBER_SEQ",
        initialValue = 1, allocationSize = 50)
  • 미리 메모리를 50을 할당받고 1씩 사용하는 것이다.
  • 만약, 50이 다 차면 다시 50을 할당해 100을 사용한다.
Member member1 = new Member();
member1.setUsername("a");
Member member2 = new Member();
member2.setUsername("b");
Member member3 = new Member();
member3.setUsername("c");

System.out.println("=====");
em.persist(member1); // 1, 51
em.persist(member2); // MEM
em.persist(member3); //MEM

System.out.println("member1 = " + member1.getId());
System.out.println("member2 = " + member2.getId());
System.out.println("member3 = " + member3.getId());
System.out.println("=====");
tx.commit();
  • 이렇게 했을 때 현재 SEQ 값은 51이 나온다.
  • 증가량은 50씩 증가하게 된다.
  • 이론상 많이 하면 좋긴 한데 50~100 정도하면 적당하다.
  • 미리 값을 올려두는 방식이기 때문에 웹 서버 여러대가 호출해도 미리 확보를 해두기 때문에 문제가 없다.
    • 동시성 문제가 없다.

자바 ORM 표준 JPA 프로그래밍 - 기본편을 참고하여 공부하였습니다.

반응형

댓글