본문 바로가기
Back-End/Database

[JPA] 고급 매핑(상속 관계 매핑, @MappedSuperclass)

by 달의 조각 2023. 1. 23.
이 글은 김영한 님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 강의를 수강하며 정리한 글입니다.

 

상속 관계 매핑
@MappedSuperclass

 


 

상속 관계 매핑

 

  관계형 데이터베이스는 상속 관계가 없다. 모델링 기법 중 슈퍼 타입 서브 타입 관계가 객체의 상속과 유사하다. 슈퍼 타입 서브 타입 논리 모델을 실제 물리 모델로 구현하는 방법에는 세 가지 방법이 있다.

 

🌕 조인 전략

  각각 테이블로 변환한다. 장점은 테이블 정규화가 되어 있고, 외래 키 참조 무결성 제약 조건을 활용할 수 있다는 점과 저장 공간이 효율화 되어 있다는 것이다.

단점은 조회 시 조인을 많이 사용해서 성능이 저하되고, 조회 쿼리가 복잡하다는 것이다. (ALBUM의 데이터를 조회하려면 ITEM과 조인 해야 한다) 또한 데이터 저장 시 INSER SQL이 2번 호출된다. 치명적인 단점은 아니다.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn // DTYPE: 엔티티 명이 들어간다
public abstract class Item {
    ...
}
@Entity
@DiscriminatorValue("M") // DTYPE: 지정하고 싶은 경우
public class Movie extends Item {
    ...
}

 

🌕 단일 테이블 전략

  통합 테이블로 변환한다. 장점은 조인이 필요 없으므로 일반적으로 조회 성능이 빠르고, 조회 쿼리가 단순하다는 것이다. 단점은 자식 엔티티가 매핑한 컬럼은 모두 null을 허용한다는 점이다. 또한 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있고, 상황에 따라 조회 성능이 오히려 느려질 수 있다.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn // SINGLE_TABLE은 DTYPE이 필수이므로 생략 가능
public abstract class Item {
    ...
}
create table Item (
    DTYPE varchar(31) not null,
    id bigint not null,
    name varchar(255),
    price integer not null,
    artist varchar(255),
    author varchar(255),
    isbn varchar(255),
    actor varchar(255),
    director varchar(255),
    primary key (id)
)

 

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

더보기

서브 타입 테이블로 변환한다. 이 전략은 데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않는다.

장점은 서브 타입을 명확하게 구분해서 처리할 때 효과적이다. not null 제약 조건을 사용할 수 있다. 단점은 여러 자식 테이블을 함께 조회할 때 성능이 느리다. (UNION SQL 필요) 또한 자식 테이블을 통합해서 쿼리하기 어렵다.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
    ...
}

 


 

@MappedSuperclass

 

  데이터베이스와는 관계 없이 객체 입장에서 공통 매핑 정보가 필요할 때 사용한다. (id, name)

상속 관계 매핑과는 다르고, 자식 클래스에 매핑 정보만 제공할 뿐 엔티티가 아니기 때문에 테이블과 매핑되지 않는다. 조회와 검색(em.find(BaseEntity))이 불가능하다. 직접 생성해서 사용할 일이 없으므로 추상 클래스로 만든다.

@MappedSuperclass
public abstract class BaseEntity {
    // 모든 테이블(엔티티)에 공통으로 포함되는 필드
}
@Entity
public class Member extends BaseEntity {
    ...
}

댓글