본문 바로가기

Dev/JPA

JPA 상속관계 매핑

객체는 상속관계를 지원하기 때문에 표현할 수 있는데

테이블 관계에 있어서는 상속을 표현하기 위해서는 여러가지 전략이 있다.

 

주요 어노테이션

@Inheritance(strategy=InheritanceType.XXX) ex) InheritanceType.JOINED / 내가 직접 전략을 지정해서 사용할 수 있다.

 → 어노테이션의 값만 바꿨을 뿐인데  JPA가 이에 맞춰서 알아서 변경해준다. JPA의 장점 중 하나!!

  • JOINED : 조인전략
  • SINGLE_TABLE : 단일 테이블 전략
  • TABLE_PER_CLASS : 구현 클래스마다 테이블 전략

조인전략(JOINED) : 이 전략이 제일 정석!!!

조인전략(JOINED)

@DiscriminatorColumn(name=“DTYPE”)

 → 조인전략에서는 어떤 타입인지 알 수 있게 적어주는 것이 좋은데 그때 사용함

@DiscriminatorValue(“XXX”)

 → 기본 default 값은 엔티티명(클래스명)을 따라가는데 다른이름으로 명해줄 경우 자식엔티티에 사용

 

장점

  1. 데이터가 정규화가 되어있고 제약조건이나 이런것을 공통(ITEM)에 걸 수 있다.
  2. 외래 키 참조 무결성 제약조건 활용 가능
  3. 저장공간의 효율화

단점

  1. 조회시 조인을 많이 사용, 성능 저하 / 조인을 어떻게 하느냐에 따라서 성능을 많이 개선할 수 있음
  2. 조회 쿼리가 복잡함
  3. 데이터 저장시 INSERT SQL 2번 호출 / 이거는 크게 단점이라고 생각안해도 된다.

단일테이블전략(SINGLE_TABLE) : 복잡하지 않은 경우에 선택하면 좋다!!!!

단일 테이블 전략(SINGLE_TABLE)

 → @DiscriminatorColumn 어노테이션이 없어도 DTYPE을 생성해준다.

 → insert도 심플하게 한번만 인서트 한다.

 → select도 마찬가지로 심플하게 한번만 조회한다.

 

장점

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

단점

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

구현 클래스마다 테이블 전략(TABLE_PER_CLASS) : 이 전략은 사용하면 안되는 전략이다 명심!!!!!

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

조인전략이랑 비슷하지만 따로 공통으로 사용하는 컬럼들을 ITEM 테이블과 같이 따로 빼는것이 아님

공통적인 컬럼들을 각각의 테이블에 다 중복되서 넣어주고 공통테이블을 따로 명시하지 않음

이 전략은 데이터베이스 설계자와 ORM 전문가 둘다 추천하지 않음

 

장점

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

단점

  1. 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL) : 만드는 것은 상관없지만 조회시 모든 테이블을 다 뒤져서 찾아야 한다.
  2. 자식 테이블을 통합해서 쿼리하기 어려움

@Mapped Superclass -  매핑 정보 상속 / 공통 매핑 정보가 필요할 때 사용

 → 예를들어서 누가 수정했는지 수정한 날짜가 언제인지 등을 항상 넣어줘야 한다??

  1. 테이블과 관계 없고 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할
  2. 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통으로 적용하는 정보를 모을 때 사용
  3. 참고 : @Entity 클래스는 엔티티나 @MappedSuperclass 지정한 클래스만 상속 가능

@MappedSuperclass : 여기에 있는 속성을 같이 쓰고 싶어!! 할 때 사용

 → 이 어노테이션이 붙은 쪽에는 실제 생성해주는 것이 아니기 때문에 추상클래스로 사용하는  것이 좋다.

@Column 어노테이션으로 지정한 값들도 공통으로 적용된다.

/*
    @MappedSuperclass : 여기에 있는 속성을 같이 쓰고 싶어!! 할 때 사용
    @Column 어노테이션으로 지정한 값들도 공통으로 적용된다.
    엔티티가 아니고 테이블을 만들어주는게 아니고 속성만 내려주는 역할을 한다..
    직접 생성하는 것이 아니기 때문에 추상클래스를 권장함
 */
//@Entity : 상속관계 일때 사용
@MappedSuperclass : 속성만 상속받을 때 사용
public abstract class BaseEntity {

    private String createdBy;
    private LocalDateTime createdDate;
    private String lastModifiedBy;
    private LocalDateTime lastModifiedDate;

주의사항

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

 

 

'Dev > JPA' 카테고리의 다른 글

JPA의 사용  (0) 2021.04.09
프록시와 연관관계 관리  (0) 2020.08.08
다양한 연관관계 매핑  (0) 2020.07.28
연관관계 매핑 기초  (0) 2020.07.15
엔티티 매핑  (0) 2020.07.12