과정을 즐기자

고급 매핑 본문

Spring Data

고급 매핑

320Hwany 2022. 12. 4. 21:24

상속 관계 매핑

관계형 데이터베이스에는 객체지향 언어에서 다루는 상속이라는 개념이 없다. 대신 슈퍼타입 서브타입 관계라는 모델링 기법이
객체의 상속 개념과 가장 유사하다. ORM에서 이야기하는 상속 관계 매핑은 객체의 상속 구조와 데이터베이스의 슈퍼타입 서브타입 관계를
매핑하는 것이다.

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

  1. 각각의 테이블로 변환하는 조인 전략
  2. 통합 테이블로 변환하는 단일 테이블 전략
  3. 서브타입 테이블로 변환하는 구현 클래스마다 테이블 전략

밑에서 설명할 예시에는 모두 Item 클래스를 부모 클래스로 만들고 Album, Movie, Book을 자식 클래스로 만들었다고 하자.

조인 전략

엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모 클래스의 기본 키를 받아서 기본 키 + 외래 키 로 사용하는 전략이다.
또한 테이블은 타입의 개념이 없으므로 타입을 구분하는 컬럼을 추가해야 한다.

부모 클래스에 다음과 같은 어노테이션을 적용한다.

@Inheritance(strategy = InheritanceType.JOINED) // - (1)
@DiscriminatorColumn // - (2)

(1)은 조인 전략을 사용하기 위한 것이고 (2)는 구분 컬럼의 값을 지정해주는 것이다. 기본 값은 DTYPE이다.

이 전략의 장점은 테이블이 정규화되고 저장공간을 효율적으로 사용할 수 있다는 점이다.
단점은 조회를 할 때 조인을 많이 사용하고 조회 쿼리가 복잡해진다.
또한 데이터를 등록할 때 INSERT SQL을 두 번 실행한다. (자식, 부모 테이블 모두 등록)

단일 테이블 전략

단일 테이블 전략은 테이블을 하나만 사용한다. 구분 컬럼으로 어떤 자식 데이터가 저장 되었는지 구분한다.
이때 구분 컬럼이 없으면 어떤 엔티티인지 구분할 수 없으므로 구분 컬럼을 꼭 사용해야 한다.

@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // - (1)
@DiscriminatorColumn // - (2)

(1)은 단일 테이블 전략을 사용하기 위한 것이고 (2)는 구분 컬럼 값을 지정해주는 것이다. 기본 값은 DTYPE이다.
이 전략의 장점은 조인이 필요가 없으므로 일반적으로 조회 성능이 빠르고 조회 쿼리가 단순하다는 것이다.
단점은 자식 엔티티가 매핑한 컬럼은 모두 null 값을 허용해야 한다. 또한 단일 테이블에 모든 것을 저장하므로
테이블이 커질 수 있다.

구현 클래스마다 테이블 전략

이 전략은 자식 엔티티마다 테이블을 만드는 전략으로 여러 자식 테이블을 함께 조회할 때 성능도 느리고
통합해서 쿼리하기도 힘들다. 데이터베이스 설계자, ORM 전문가 둘 다 추천하지 않는 전략이므로
조인, 단일 테이블 전략을 사용하자.

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

일반적으로 조인 전략을 사용하고 부모, 자식 클래스 관계가 단순할 경우 단일 테이블 전략을 고려해보자.

MappedSuperclass

엔티티에서 공통으로 사용하는 속성들이 있다. 예를들면 등록일자, 수정일자, 등록자, 수정자가 있다.
@MappedSuperclass는 이러한 공통 매핑 정보가 필요할 때 사용한다.
매핑 정보를 상속할 부모 클래스에 @MappedSuperclasss 어노테이션을 붙여주어 사용한다.
이것은 객체에서 부모 클래스를 상속받은 자식 클래스에게 매핑 정보만 제공한다.
상속관계 매핑이 아니다. 따라서 엔티티도 아니고 테이블과 매핑도 되지 않는다.

출처 : 자바 ORM 표준 JPA 프로그래밍 (김영한)

'Spring Data' 카테고리의 다른 글

값 타입  (0) 2022.12.11
프록시와 연관관계 관리  (0) 2022.12.06
다양한 연관관계 매핑  (0) 2022.12.02
연관관계 매핑  (0) 2022.11.29
엔티티 매핑  (0) 2022.11.29