Chapter 7: 고급 매핑

1. 상속 관계 매핑

  • 관계형 데이터베이스는 상속 이라는 개념이 없다

    • 대신에 Super-Type Sub-Type 관계라는 모델링 기법이 객체의 상속 개념과 가장 유사하다

    • ORM에서 이야기하는 상속 관계 매핑은 객체의 상속 구조와 데이터베이스의 슈퍼타입 서브타입 관계매핑하는 것이다

  • 슈퍼타입 서브타입 논리 모델을 실제 물리 모델인 테이블로 구현하는 방법 3가지

    1. 각각의 테이블로 변환

      • 각각을 모두 테이블로 만들고 조회할 때 조인을 사용

      • JPA에서는 조인 전략이라 한다

    2. 통합 테이블로 변환

      • 테이블을 하나만 사용해서 통합

      • JPA에서는 단일 테이블 전략이라 한다

    3. 서브 타입 테이블로 변환

      • 서브 타입마다 하나의 테이블을 만든다

      • JPA에서는 구현 클래스마다 테이블 전략 이라 한다

1-1. 조인 전략

  • 엔티티 각각을 모두 테이블로 만들고, 자식 테이블이 부모 테이블의 기본 키 를 받아서 기본 키 + 외래 키 로 사용하는 전략

    • 조회할 때 JOIN을 자주 사용!

  • 주의할 점

    • 객체는 타입으로 구분할 수 있지만, 테이블은 타입의 개념이 없다

      • 따라서 타입을 구분하는 칼럼을 추가해야 한다!

  • 장점

    • 테이블이 정규화된다

    • 외래 키 참조 무결성 제약조건을 활용할 수 있다

    • 저장공간을 효율적으로 사용한다

  • 단점

    • 조회할 때 조인이 많이 사용되므로 성능이 저하될 수 있다

    • 조회 쿼리가 복잡하다

    • 데이터를 등록할 INSERT SQL을 두 번 실행한다

  • 특징

    • 하이버네이트를 포함한 몇몇 구현체는 구분 컬럼 없이도 동작한다

1-2. 단일 테이블 전략

  • 이름 그대로 테이블을 하나만 사용하고, 구분 컬럼으로 어떤 자식 데이터가 저장되었는지 구분

    • 조회할 때 조인을 사용하지 않으므로 일반적으로 가장 빠름!

  • 주의할 점

    • 자식 엔티티가 매핑한 컬럼은 모두 null을 허용 한다는 점

  • 장점

    • 조인이 필요 없으므로 일바넞긍로 조회 성능이 빠르다

    • 조회 쿼리가 단순하다

  • 단점

    • 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 한다

    • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다

      • 상황에 따라서는 조회 성능이 오히려 느려질 수 있따

  • 특징

    • 구분 컬럼을 꼭 사용해야 한다!

      • @DiscriminatorColumn 설정 필수!

    • @DiscriminatorColumn 을 지정하지 않으면 기본으로 엔티티 이름 을 사용한다

1-3. 구현 클래스마다 테이블 전략

  • 자식 엔티티마다 테이블을 만든다

    • 자식 테이블에 각각 필요한 칼럼이 모두 있다

    • 일반적으로 추천하지 않는 전략!

  • 장점

    • 서브 타입을 구분해서 처리할 때 효과적

    • not null 제약 조건 사용 가능

  • 단점

    • 여러 자식 테이블을 함께 조회할 때 성능이 느리다

      • SQL에 UNION을 사용해야 한다

    • 자식 테이블을 통합해서 쿼리하기 어렵다

  • 특징

    • 구분 컬럼을 사용하지 않는다

2. @MappedSuperClass

  • 부모 클래스는 테이블과 매핑하지 않고, 부모 클래스를 상속 받는 자식 클래스에게 매핑 정보만 제공하고 싶으면 @MappedSuperClass 를 사용하면 된다

  • @MappedSuperClass 는 추상 클래스와 비슷한데, @Entity 는 실제 테이블과 매핑되지만 @MappedSuperClass 는 실제 테이블과 매핑되지 않는다

    • 단순히 매핑 정보를 상속할 목적으로만 사용된다

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

  • @MappedSuperClass 를 사용하면 등록 일자, 수정 일자, 등록자, 수정자와 같은 여러 엔티티에서 공통으로 사용하는 속성을 효괒거으로 관리할 수 있따

3. 복합 키와 식별 관계 매핑

3-1. 식별 관계 vs 비식별 관계

  • 식별 관계

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

  • 비식별 관계

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

    • 필수적 비식별 관계

      • 외래 키에 NULL을 허용하지 않음

      • 연관관계를 필수적으로 맺어야 함

    • 선택적 비식별 관계

      • 외래 키에 NULL을 허용함

      • 연관관계를 맺을지 말지 선택할 수 있음

3-2. 복합 키: 비식별 관계 매핑

  • JPA에서 식별자를 둘 이상 사용하려면, 별도의 식별자 클래스를 만들어야 한다

  • JPA는 복합 키를 지원하기 위해 @IdClass@EmbeddedId 2가지 방법을 제공한다

  • @IdClass

    • 식별자 클래스의 조건

      • 식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 한다

      • Serializable 인터페이스를 구현해야 한다

      • equals, hashcode를 구현해야 한다

      • 기본 생성자가 있어야 한다

      • 식별자 클래스는 public이어야 한다

  • @EmbeddedId

    • 식별자 클래스에 기본키를 직접 매핑한다

    • 식별자 클래스의 조건

      • @Embeddable 어노테이션을 붙여주어야 한다

      • Serializable 인터페이스를 구현해야 한다

      • equals, hashcode를 구현해야 한다

      • 기본 생성자가 있어야 한다

      • 식별자 클래스는 public이어야 한다

Last updated