본문 바로가기
Programming/Spring

[JPA] 상속관계 매핑

by peter paak 2021. 3. 4.
728x90

  • 관계형 데이터베이스는 상속관계 x
  • 부모만 @Id를 가진다, @Entity는 모두 가진다
  • 슈퍼타입, 서브타입이 객체 상속과 비슷하다

전략

  1. 조인전략 : 각각의 테이블을 조인
    • 테이블 정규화
    • 외래키 참조 무결성 제약조건 활용 가능
    • 저장 공간 효율화
    • 조회시 조인 사용하여 성능저하
    • 데이터 저장시 Insert 쿼리 두번 이상 사용
    • 정석!!!, 설계 깔끔!!!, 조인만 잘하면 되지!!!
    • 중요하고 복잡한 비즈니스 로직!!!
  2. 단일테이블 전략 : 통합 테이블에서 단일 테이블로 = 성능좋다
    • 조인이 없어서 빠른 성능
    • 단순한 조회쿼리
    • 자식 엔티티가 매핑한 컬럼은 모두 null 허용
    • 테이블이 커질 수 있다 ⇒ 조회가 느려질 수도 있다
    • 확장 가능성 없을 때!!!
  3. ~~클래스마다 테이블 전략 :구현 클래스마다 테이블~~

  • 슈퍼클래스 : Item
  • 서브클래스 : Album, Movie, Book
  • DTYPE으로 Album, Movie, Book 구분 가능
@Inheritance(strategy) 
    - JOINED
    - SINGLE_TABLE
    - TABLE_PER_CLASS
@DiscriminatorColumn // 서브타입 구분자 (ex. DTYPE)
@DiscriminatorValue  // 서브타입의 값 (ex. B)

슈퍼타입

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item{

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private int price;

}

서브타입

@Entity
@DiscriminatorValue("P")
public class Picture extends Item{

    private String artist;
}

@MappedSuperclass

  • 상속관계 매핑 아니다
  • 엔티티 아니다
  • 테이블 매핑 아니다
  • 여러 엔티티에서 반복적으로 사용되는 컬럼을 제공 (AOP와 같은 개념)
  • 단순히 커럼만 제공한다 (상속이고 뭐고 아무것도 아니다)
  • 조회, 검색 불가
  • 직접 생성해서 사용할 일 없으므로 추상클래스 권장
  • 공통 매핑정보가 필요할 때 사용 (createdAt, modifiedAt)
@MappedSuperclass
public abstract class BaseEntity {

    private String createdBy;

    private LocalDateTime createdDate;

    private String modifiedBy;

    private LocalDateTime modifiedDate;
}
public abstract class Item extends BaseEntity{}

(추가) @EnableJpaAuditing

MappedSuperClass에서 사용하는 createdDate 등은 일일이 값을 넣어주기가 번거로운데 데이터베이스에 입력시 자동으로 값을 입력해준다

  • 주의, @CreatedBy, @CreatedDate 등 AuditingEntityListener는 @MappedSuperclass와는 관계가 없다
  • @MappedSuperclass는 단순히 extend된 엔티티들에 공통되는 column을 제공하기 위해 사용된다
@EnableJpaAuditing

BaseEntity

@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {

    @CreatedBy
    private String createdBy;

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedBy
    private String modifiedBy;

    @LastModifiedDate
    private LocalDateTime modifiedDate;
}
728x90