[JPA/김영한] 고급 매핑 알아보자

수영·2021년 10월 4일
2

JPA 공부!

목록 보기
6/9

이 글은 김영한님의 JPA 강의 중 7장 고급 매핑을 듣고 정리한 내용입니다 :)
강의 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
교재 : 자바 ORM 표준 JPA 프로그래밍🤷‍♀️


❓ 상속관계는 매핑을 어떻게 하나?

: JPA는 객체의 상속과 DB의 슈퍼/서브 타입 관계를 매핑해준다
(관계형 DB에는 상속관계가 없음, 그나마 슈퍼-서브 타입이 객체의 상속과 유사함!)

이 상속관계 매핑에는 3가지 방법이 있는데,
보통은 1번을 사용, 설계가 단순한 경우는 2번을 사용하기도 한다. 그리고 3번은 절대 쓰지 말자-!

  1. 조인 (기본적으로 사용)
  2. 단일 테이블 (정말 단순한 설계일 경우 사용)
  3. 클래스마다 각각 테이블로 만들기 (사용X)

이 3가지의 방법은,
우선 엔티티 다 코드 짜고, 그냥 어노테이션만 변경하면 다른 방법으로 바로 바꿀수 있다.
=> 이게 JPA의 편한점이다! 전략 바뀔때마다 코드를 다 다시 짜는 게 아니라, 어노테이션만 변경하면 된다!

@Inheritance(strategy = InheritanceType.JOINED)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)


1. 조인 전략 (기본)

: 각각 테이블로 만들고 슈퍼타입에 조인시킴! 기본적으로 주로 사용한다.
슈퍼타입 엔티티에 @Inheritance(strategy = InheritanceType.JOINED)

이때 슈퍼 타입에 속성으로 DTYPE을 두어서, 슈퍼타입 테이블만 보고도 어떤 서브타입인지 구분함 (사실 이 전략에서는 없어도 가능함, 2번에서는 필수)

  • 장점 : 상속 기능 활용(자식 클래스들의 전체 price를 구할때라던지), 외래키 참조할 때도 부모의 PK만 찾으면 OK, 저장 공간 효율화
  • 단점 : 조회 시 조인 많이 사용, 쿼리 2번 호출 ⇒ 근데 이것들은 큰 문제는 아님

// 슈퍼 타입 엔티티
@Entity
@Inheritance(strategy = InheritanceType.JOINED) //첫번째 전략!
@DiscriminatorColumn // 기본이름은 DTYPE
public class Item
{
    @Id @GeneratedValue
    private Long id;
    private String name;
}

// 서브 타입 엔티티 중 Album
@Entity
@DiscriminatorValue // 기본은 엔티티 이름 (여기서는 Album)
public class Album extends Item
{
    private String artist;
}

2. 단일 테이블

: 모든 속성을 하나의 테이블에 몰아넣기, 정말 단순한 설계일 경우 사용한다.
슈퍼타입 엔티티에 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)

여기서는 슈퍼 타입에 속성으로 DTYP을 꼭 설정해주어야 함! (그래야 구분 가능)

  • 장점 : 성능이 잘 나오고, 쿼리가 한번에, 조인할 필요 없음
  • 단점 : 속성들이 다 null이 허용되어야하고, 오히려 성능이 느려질 수 있음 (보통은 성능이 느려질정도까지는 아니긴하나 참고)

// 슈퍼 타입 엔티티
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) //두 번째 전략!
@DiscriminatorColumn
public class Item
{
    @Id @GeneratedValue
    private Long id;
    private String name;
}

3. 클래스마다 각각 테이블로 만들기

: 상속도 아니고 그냥 서브타입들을 단일 테이블로 만듦. 이건 그냥 쓰지 말것

  • 장점 : 생성은 쉬움
  • 단점 : 상속의 장점을 전혀 못 사용함 (price 전체 구하는 거 못함)
    부모클래스에서 조회를 못하니까, PK로 조회시 모든 자식 테이블들을 다 찾아봐야함!

// 슈퍼 타입 엔티티
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) //두 번째 전략!
// @DiscriminatorColumn 이 어노테이션은 필요없음
public abstract class Item
{
    @Id @GeneratedValue
    private Long id;
    private String name;
}

❔ @MappedSuperclass 란

: 객체 만들때 반복되는 몇가지 속성을 저장해두고 필요할때마다 사용하기 위한 어노테이션! (매핑 정보만 상속하는 슈퍼클래스라고 생각하자)

  • 언제 사용하나 ? ⇒ 상속관계는 아니지만 몇가지 속성만 같이 쓰고 싶을때 사용하자
  • 상속관계 매핑 X, 엔티티 X, DB 테이블에 매핑 X(조회, 검색 안 됨)
  • 직접 생성할 일 없으므로 추상 클래스로 만들자

// 속성만 상속하는 슈퍼클래스
@MappedSuperclass
public abstract class BaseEntity // 엔티티 아님!
{
    private String createdBy;
    private LocalDateTime createdDate;
}

@Entity
public class Member extends BaseEntity {
...
}
profile
🎵🎵🎵🎶🎵

0개의 댓글