Ep6. 고급 매핑

yumyeonghan·2023년 2월 6일
0

JPA

목록 보기
6/10

🍃이 글은 inflearn에서 김영한의 스프링 부트와 JPA 실무 완전 정복 로드맵을 학습하고 작성한 것입니다.🍃

상속관계 매핑

  • 관계형 데이터베이스는 상속 관계 개념이 없다.

  • 대신 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사하다.

  • 상속관계 매핑이란 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑한다.

주요 어노테이션

  • @Inheritance(strategy=InheritanceType.XXX)

    • JOINED: 조인 전략
    • SINGLE_TABLE: 단일 테이블 전략
    • TABLE_PER_CLASS: 구현 클래스마다 테이블 전략
  • @DiscriminatorColumn(name=“DTYPE”)

    • 부모 클래스에 선언한다.
    • 하위 클래스를 구분하는 용도의 컬럼이다.
    • 관례는 default 값인 DTYPE을 사용한다.
  • @DiscriminatorValue(“XXX”)

    • 하위 클래스에 선언한다.
    • 엔티티를 저장할 때 슈퍼타입의 구분 컬럼에 저장할 값을 지정한다.
    • 어노테이션을 설정하지 않을 경우 기본값으로 클래스 이름이 지정된다.
@Entity
@Inheritance(strategy = InheritanceType.XXX) // 상속 구현 전략 선택
public class Item {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   private String name;
   private int price;
}
  • 부모 클래스인 Item 엔티티

@Entity
public class Album extends Item {

   private String artist;
}
  • 자식 클래스인 Album 엔티티

@Entity
public class Movie extends Item {

   private String director;
   private String actor;
}
  • 자식 클래스인 Movie 엔티티

@Entity
public class Book extends Item {

   private String author;
   private String isbn;
}
  • 자식 클래스인 Book 엔티티

상속관계 매핑 3가지 전략

    1. 조인 전략

    • 가장 정규화된 방법으로 구현하는 방식이다.
    • NAME, PRICE가 ITEM 테이블에만 저장되고, ALBUM, MOVIE, BOOK이 각자의 데이터만 저장한다.
    • 장점
      • 테이블 정규화
      • 테이블 정규화로 저장공간 효율화
      • 외래키 참조, 무결성, 제약조건 활용 가능
    • 단점
      • 조회 쿼리가 복잡함
    1. 단일 테이블 전략

    • 한 테이블에 다 저장하고, DTYPE으로 구분한다.
    • 장점
      • 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
      • 조회 쿼리가 단순함
    • 단점
      • 자식 엔티티가 매핑한 컬럼은 모두 null을 허용
      • 테이블에 모든 것을 저장해서 커질 수 있음
    1. 구현 클래스마다 테이블 전략
    • 이 전략은 사용하지 않는다.

기본 전략을 조인 전략으로 하되 두 전략의 장단점을 비교해서 선택하자.

  • 비즈니스적으로 단순하고 확장 가능성이 작으면 단일 테이블 전략을 사용하자.
  • 비즈니스적으로 복잡하고 확장 가능성이 크면 조인 전략을 사용하자.

@MappedSuperclass

등록일, 수정일, 등록자, 수정자 등을 모든 엔티티에 공통으로 적용해야 한다면 많은 중복이 발생하는 문제가 생긴다. 어떻게 해결할까?

  • 객체의 입장에서 공통 매핑 정보가 필요할 때 사용한다.

  • id, name은 객체의 입장에서 볼 때 계속 나온다.

  • 이렇게 공통 매핑 정보가 필요할 때, 부모 클래스에 선언하고 속성만 상속받아서 사용하고 싶을 때 @MappedSuperclass를 사용한다.

  • DB 테이블과는 상관없다. 단지 객체의 입장이다.

@Getter
@Setter
@MappedSuperclass
public abstract class BaseEntity {

   private String createdBy;

   private LocalDateTime createdDate;

   private String lastModifiedBy;

   private LocalDateTime lastModifiedDate;
}
  • 위와 같이 BaseEntity를 정의해서 활용할 수 있다.

  • 매핑 정보만 상속받는 Superclass라는 의미의 @MappedSuperclass 어노테이션 선언


@Entity
public class Member extends BaseEntity {
  ...
}
  • BaseEntity 상속받아서 사용한다.

@Entity
public class Team extends BaseEntity {
  ...
}
  • BaseEntity 상속받아서 사용한다.

  • 정리

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

    • 상속관계 매핑이 아니다.

    • 엔티티가 아니다.

    • 테이블과 매핑되지 않는다.

    • 부모 클래스를 상속받는 자식 클래스에 매핑 정보만 제공한다.

    • 따라서 조회, 검색이 불가하다.

    • 직접 생성해서 사용할 일이 없으므로 추상 클래스로 정의하자.

  • JPA에서 @Entity 클래스는 @Entity나 @MappedSuperclass로 지정한 클래스만 상속할 수 있다.

profile
웹 개발에 관심 있습니다.

0개의 댓글