상속관계 매핑

Jaca·2021년 8월 22일
0

상속 관계

우리는 객체를 상속관계를 통해 개발 할 경우가 있다.
하지만 관계형 데이터베이스는 상속 관계라는 개념이 존재하지 않는다.

그래서 슈퍼타입, 서브타입 관라는 모델링 기법을 사용해서 상속 관계를 매핑한다.


이번에 사용할 예제.

주요 어노테이션

  • Inheritance(strategy=InheritanceType.XXX)
    속성에 있는 전략엔 총 세가지
    JOINED, SINGLE_TABLE, TABLE_PER_CLASS가 있다.

  • @DiscriminatorColumn(name=“DTYPE”)
    @DiscriminatorColumn 애노테이션을 통해 DTYPE을 줄 수 있다. ENTITY 명이 데이터로 들어갑니다. name을 다른이름으로 주면 ITEM에 DTYPE 컬럼대신 다른 컬럼명이 생성된다.

  • @DiscriminatorValue(“XXX”)
    @DiscriminatorValue를 통해 Entity명 대신 특정 명칭을 넣어줄 수 있다.

조인 전략

슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법 중 각각의 테이블로 변환해서 조인 하는 방법이다.

전략을 조인으로 설정하고, Movie 정보를 저장하고 찾아와 보았다.

h2콘솔을 보면 각각의 테이블이 모두 만들어지고 데이터가 들어가있다.

쿼리를 보면 insert를 Item과 Movie 테이블에 시켜주고 select 할때는
join 쿼리를 사용해서 데이터를 가져오는 것을 볼 수 있다.

조인 전략의 장점

  • 테이블 정규화
  • 외래 키 참조 무결성 제약조건 활용가능
  • 저장공간 효율화

조인 전략의 단점

  • 조회시조인을많이사용,성능저하
  • 조회 쿼리가 복잡함
  • 데이터 저장시 INSERT SQL 2번 호출

단일 테이블 전략

직관적으로 알 수 있듯이, 하나의 테이블에 때려 박는다고 생각하면 된다.

모든 속성을 상위 테이블에 때려 넣어서 하나의 테이블만 생성한다.

조인 전략에서는 Item, Moive, Album, Book 4개의 테이블이 생성되었는데, Item 테이블 하나로 통합된 것을 알 수있다.
딱히 보지 않아도 SQL문의 결과도 대충 예상이 갈 것이다.

단일 테이블 전략의 장점

  • 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
  • 조회 쿼리가 단순함

단일 테이블 전략의 단점

  • 자식 엔티티가 매핑한 컬럼은 모두 null 허용
  • 단일테이블에 모든것을 저장하므로 테이블이 커질수있다.
    상황에 따라서 조회 성능이 오히려 느려질 수 있다.

구현 테이블 마다 테이블을 생성

위 두 전략은 abstract 클래스인 Item 클래스를 이용해왔다.
이 전략은 공통 속성인 Item 클래스의 속성을 자식 클래스에 넘겨서 구체 클래스를 테이블로 생성한다.

3개의 구체 클래스만 테이블로 생성되었다.

구체 테이블 전략의 장점

  • 서브 타입을 명확하게 구분해서 처리할 때 효과적
  • not null 제약조건 사용 가능

구체 테이블 전략의 단점

  • 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
  • 자식 테이블을 통합해서 쿼리하기 어려움

하지만 이 전략은 데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않는다.
JPA로 엔티티 조회시 타입을 부모 타입으로 지정하면, 부모 타입의 자식 테이블에 해당하는 모든 테이블들을 UNION하여 조회해서, 성능이 심각하게 떨어진다.

@MappedSuperclass

공통 매핑 정보가 필요할 때 사용한다.

위에서 알아본 Item 클래스와 같은 상속 관계와는 느낌이 다르다.
테이블과 관계 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할로써, 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통 으로 적용하는 정보를 모을 때 사용한다.
@Entity 클래스는 엔티티나 @MappedSuperclass로 지정한 클래스만 상속 가능하다.

이 어노테이션을 사용할 때의 주요 특성은 아래와 같다.

  • 상속관계 매핑이 아니다.
  • 엔티티가 아니다. 테이블과 매핑하지 않는다.
  • 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공
  • 조회, 검색 불가(em.find(BaseEntity) 불가)
  • 직접 생성해서 사용할 일이 없으므로 추상 클래스 권장

@MappedSuperclass
public class BaseEntity {
    private String createdBy;
    private LocalDateTime createdDate;
    private String modifiedBy;
    private LocalDateTime lastModifiedBy;
}

위와 같은 공통 속성을 Member와 Team 클래스에 넣고자 한다.

BaseEntity의 정보가 추가되어 테이블이 생성되었다.

profile
I am me

0개의 댓글