Backend/Spring Boot

[자바 ORM 표준 JPA 프로그래밍] 7장

lim.dev 2023. 5. 23. 17:22

7장 고급 매핑

 

  • 상속 관계 매핑
  • @MappedSuperclass
  • 복합 키와 식별 관계 매핑
  • 조인 테이블
  • 엔티티 하나에 여러 테이블 매핑

 

상속 관계 매핑

 

슈퍼타입 서브타입 논리 모델을 실제 물리 모델인 테이블로 구현할 때는 3가지 방법을 선택할 수 있음

 

1. 각각의 테이블로 변환 (조인 전략)

  • 엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 테이블의 기본 키를 받아서 기본키 + 외래키로 사용하는 전략
  • 조회할 때 조인을 자주 사용
  • 주의점: 객체는 타입으로 구분할 수 있지만 테이블은 타입의 개념이 없음 -> 타입을 구분하는 컬럼을 추가해야 함
    • 예제에서는 DTYPE 컬럼을 구분 컬럼으로 사용
  • 조인 전략
    • 장점
      • 테이블이 정규화 됨
      • 외래키 참조 무결성 제약조건을 활용할 수 있음
      • 저장공간을 효율적으로 사용함
    • 단점
      • 조회할 때 조인이 많이 사용되므로 성능 저하될 수 있음
      • 조회 쿼리가 복잡함
      • 데이터를 등록할 INSERT SQL을 두 번 실행
    • 특징
      • JPA 표준 명세는 구분 컬럼을 사용하도록 하지만 하이버네이트를 포함한 몇몇 구현체는 구분컬럼 없이도 동작

 

2. 통합 테이블로 변환 (단일 테이블 전략)

  • 이름 그대로 테이블을 하나만 사용
  • 구분컬럼 (DTYPE)으로 어떤 자식 데이터가 저장되었는지 구분
  • 조회할때 조인하지 않음 -> 일반적으로 가장 빠름
  • 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 함 
  • 단일 테이블 전략
    • 장점
      • 조인이 필요 없음 -> 조회 성능 빠름
      • 조회 쿼리가 단순
    • 단점
      • 자식 엔티티가 매핑한 컬럼은 모두 null 허용
      • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있음 -> 상황에 따라 조회 성능이 느려질 수 있음
    • 구분 컬럼을 꼭 사용해야 함

 

3. 서브타입 테이블로 변환 (구현 클래스마다 테이블 전략)

  • 자식 엔티티마다 테이블을 만드는 것 (자식 테이블에 각각 필요한 컬럼이 모두 있음)
  • 일반적으로 추천하지 않음
  • 구현 클래스마다 테이블 전략
    • 장점
      • 서브 타입을 구분해서 처리할 때 효과적
      • not null 제약조건 사용 가능
    • 단점
      • 여러 자식 테이블을 함께 조회할 때 성능이 느림 (SQL UNION을 사용해야 함)
      • 자식 테이블을 통합해서 쿼리하기 어려움
    • 특징
      • 구분 컬럼 사용하지 않음

 

@MappedSuperclass

부모 클래스는 테이블과 매핑하지 않고 부모 클래스를 상속 받는 자식 클래스에게 매핑 정보만 제공하고 싶을때 사용

@Entity는 실제 테이블과 매핑되지만 @MappedSuperclass는 실제 테이블과는 매핑되지 않음

단순히 매핑 정보를 상속할 목적으로 사용됨

회원과 판매자는 서로 관계가 없는 테이블과 엔티티일때 테이블은 그대로 두고 객체 모델의 id, name 두 공통 속성을 부모 클래스로 모아서 상속 관계로 만드는 것

즉, 테이블과 관계가 없고 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모아주는 역할을 함

 

복합 키와 식별 관계 매핑

식별 관계 vs 비식별 관계

  • 식별 관계: 부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본 키 + 외래 키로 사용하는 관계

  • 비식별 관계: 부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계

비식별 관계는 외래 키에 NULL을 허용하지 않으면 필수적 비식별 관계(연관관계 필수), NULL을 허용하면 선택적 비식별 관계(연관관계 선택적) 으로 나뉨