본문 바로가기

정보/Database

Entity Mapping

1. 객체와 테이블 매핑

  • @Entity : JPA가 관리하는 Entity
    • JPA를 사용해서 테이블과 매핑할 클래스는 필수
    • 기본 생성자 필수(파라미터가 없는 public, protected 생성자)
      • reflection등 다양한 기술을 써서 객체 proxy할 때 사용된다고는 함. spec상 그렇다.
    • final, enum, interface, inner 클래스는 사용 안된다!
    • 저장할 필드에 final 사용 X
    • 속성 : name / default는 class 이름
  • @Table : class 이름과 다른 table과 매핑하기 위해서 사용.

 

2. DB 스키마 자동 생성

  • DDL을 애플리케이션 실행 시점에 자동 생성 (production에서는 사용 X, 개발시에만)
  • 객체 중심으로 필요한 테이블 만들어준다. (DB dialect별로 DB에 맞는 적절한 DDL 생성)
<property name="hibernate.hbm2ddl.auto" value="create" />

이 속성을 추가하면 DDL 을 통해서 생성되는 것.

  • value 옵션 (운영 장비에는 절대 create, create-drop, update 사용 금지)
    • create : 기존 테이블 삭제(drop) 후 다시 생성
    • create-drop : 종료 시점에 table drop / test 끝내고 없앨 때
    • update : 변경 부분만 반영( 운영 db에는 사용하지 말 것)
    • validate : 엔티티와 테이블이 정상 매핑되었는지 확인만
    • none : DDL 사용 X
    • 개발 초기 단계는 create, update
      테스트 서버는 update, validate
      스테이징과 운영 서버는 validate, none
      • 개발, 테스트서버도 직접 하는거를 추천, 개발, 스테이징에서 쓰지 말라.
      • 운영서버에 반영할 때 정돈된 스크립트 집어넣을 때 쓴다는데...
      • 근본적으로는 alter나 drop이 안되게 막아놔야한다
  • DDL 생성 기능
    • 제약조건 추가 :  회원 이름 필수, 10자 초과X
      @Column(nullable = false, length = 10)
    • DDL 자동 생성할 때만 사용되고, 영향 줌. JPA의 실행 로직에는 영향을 주지 않는다.

 

3. 필드와 컬럼 매핑

  • @Column : 컬럼 매핑
    • name
    • insertable, updateable : INSERT나 UPDATE을 할 때 변경 가능 여부
    • nullable(DDL) : null 값 허용 여부 설정. false면 DDL 생성 시에 not null 제약 조건이 붙는다.
    • unique(DDL) : 유니크 제약 조건 -> 잘 안씀. 못알아보는 이름으로 나와서
      • -> @Table(uniqueConstraints  )를 통해 사용 한다.
    • columnDefinition(DDL) : DB 컬럼 정보를 직접 넣을 수 있다. ex) varchar(100) default 'EMPTY'
    • length(DDL) : 문자 길이 제약 조건, String 타입만
    • precision, scale : BigDecimal 타입에서 사용한다. 아주 큰 숫자나 소수점 쓸 때 
  • @Temporal : 날짜 타입 매핑
    • 굳이 사용할 필요는 없다. 최신 Hibernate는 LocalDate -> Date 타입과 매핑
    • LocalDateTime -> Timestamp와 매핑
  • @Enumerated : enum 타입 매핑
    • EnumType.ORDINAL : ENUM을 순서대로 integer로 DB에 업데이트하는데 이거 ENUM에 어떤 거 추가하거나 하면 다시 0으로 카운트하는 듯 함 -> 예측 불가능이니 사용하지 말것.
    • EnumType.STRING : 무조건 이거 쓸 것.
  • @Lob : BLOB, CLOB 매핑 (지정할 수 있는 속성은 없음.)
  • @Transient : 매핑을 안하고 싶은 필드

 

 

4. 기본 키 매핑

 

직접 할당 : @Id (어느 필드에 할당할 것인지를 적는 듯.)

자동 생성 : @GeneratedValue(strategy = GenerationType.IDENTITY, SEQUENCE, TABLE, AUTO(이건 기본값))

  • IDENTITY 전략 : 기본 키 생성을 DB에 위임
    • 문제점 : DB에 commit이 되어야 PK값을 알 수 있다. 
      • 그런데, 이 경우에 관련해서만 (IDENTITY 전략을 쓸 때만 persist 영속한 순간 바로 INSERT 쿼리가 날아감)
  • SEQUENCE 전략 : SEQUENCE 오브젝트에 맞춰 순서대로 생성하도록
    • ID에 Long을 쓰는 것을 권장.
    • persist 영속성 붙은 순간 DB로부터 SEQUENCE를 얻어온 다음에 이를 받아서 id를 입력하고, INSERT
    • 여기서는 buffering 전략이 가능하다. 
    • 근데 이런식으로 buffer를 두는게 성능상으로 ㄱㅊ한가?
      • allocationSize : next call 한 번 할때 DB에 50개를 생성하고, 50개씩 받아옴 (성능 최적화 방)
      • 동시성 이슈도 컨트롤 가능
  • TABLE 전략 : 키 생성 전용 테이블을 하나 만들어서 DB 시퀀스를 흉내내는 전략
    • 장점 : 모든 DB에 적용 가능, 단점 : 성능
    • initialValue, allocationSize (여기서도 동시성 이슈 컨트롤 가능)

권장하는 식별자 전략

기본 키 제약 조건 : null 아님, 유일, "변하면 안된다" 

근데 이걸 만족하는 자연키(비즈니스 로직있는 키)를 찾기 어렵다 -> 대리키(대체키) 사용하자

=> 권장 : Long형 + 대체키(sequence, UUID, ...) + 키 생성전략 사용

'정보 > Database' 카테고리의 다른 글

연관 관계 Mapping (3)  (0) 2024.11.17
연관 관계 Mapping (2)  (1) 2024.11.15
연관 관계 Mapping (1)  (0) 2024.11.15
JPA Persistence Context 는 Git과 흡사하다  (0) 2024.11.13
JPA : Java ORM 표준  (2) 2024.11.13