JPA ) 자바 ORM 표준 JPA 프로그래밍 - 7

GoRuth·2025년 4월 22일

JPA

목록 보기
7/8

1. 상속관계 매핑

  • DB에는 상속이라는 개념 ❌
    -> 대신 그림과 같이 슈퍼타입 서브타입 관계라는 모델링 기법이 가장 유사
  • 실제 구현 방법
    • 각각의 Table로 변환 (Join 전략)
      • 각각을 모두 테이블로 만듬
      • 조회 시 조인사용
    • 통합 테이블로 변환 (단일 테이블 전략)
      • 테이블을 하나만 사용해서 통합
    • 서브타입 테이브로 변환 (구현 클래스마다 테이블 전략)
      • 서브 타입마다 하나의 테이블을 만듬

1.1. 조인전략

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Parent {
 @Id @GeneratedValue
 @Column(name = "Parent_ID")
 private Long id;
 private String name; //이름
 private int price; //가격
}
@Entity
@DiscriminatorValue("C1")
public class Child1 extends Parent {
 private String c_1;
}
@Entity
@DiscriminatorValue("C2")
public class Child2 extends Parent {
 private String c_2; //감독
 private String c_22; //배우
}
@Entity
@DiscriminatorValue("C3")
public class Child3 extends Parent {
 private String c_3; //배우
}
  • @Inheritance(strategy = InheritanceType.JOINED)
    • 상속 매핑은 부모 클래스에 @Inheritance를 사용해야 함.
    • 매핑 전략을 지정해야 하는데, 조인 전략을 사용하므로InheritanceType.JOINED를 사용했다.
  • @DiscriminatorColumn(name = "DTYPE")
    • 부모 클래스에 구분 컬럼을 지정
    • 이 컬럼으로 저장된 자식 테이블을 구분할 수 있다. 기본값이 DTYPE이므로 @DiscriminatorColumn으로 줄여 사용해도 됨
  • @DiscriminatorValue("M")
    • 엔티티를 저장할 때 구분 컬럼에 입력할 값을 지정.
    • 만약 Child3 엔티티를 저장하면 구분 컬럼인 DTYPE에 값 C3이 저장된다.
  • 장점
    • 테이블 정규화
    • 외래 키 참조 무결성 제약조건을 활용 가능
    • 저장 공간을 효율적으로 사용
  • 단점
    • 조회할 때, 조인이 많이 사용되므로 성능이 저하 가능
    • 조회 쿼리가 복잡
    • 데이터를 등록할 Insert SQL를 두 번 실행

1.2. 단일 테이블 전략

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Parent {
 @Id @GeneratedValue
 @Column(name = "Parent_ID")
 private Long id;
 private String name;
 private int price;
}

@Entity
@DiscriminatorValue("C1")
public class Child1 extends Parent {
 private String c_1;
}

@Entity
@DiscriminatorValue("C2")
public class Child2 extends Parent {
 private String c_2;
 private String c_22;
}

@Entity
@DiscriminatorValue("C3")
public class Child3 extends Parent {
 private String c_3;
}
  • 장점

    • 조인이 필요 ❌ -> 조회 성능이 빠름
    • 조회 쿼리가 단순
  • 단점

    • 자식 Entity가 매핑한 컬럼은 모두 null 허용
    • 단일 테이블에 모든 것을 저장하여, 테이블이 커질 수 있음
      -> 상황에 따라서는 조회 성능이 오히려 느려짐
  • 특징

    • 구분 컬럼을 꼭 사용해야 함
      -> @DiscriminatorColumn 설정 필수
    • @DiscriminatorValue를 지정하지 않으면 기본으로 엔티티 이름을 사용

1.3. 구현 클래스마다 테이블 전략

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Parent {
 @Id @GeneratedValue
 @Column(name = "Parent_ID")
 private Long id;
 private String name;
 private int price;
}

@Entity
public class Child1 extends Parent {
 private String c_1;
}

@Entity
public class Child2 extends Parent {
 private String c_2;
 private String c_22;
}

@Entity
public class Child3 extends Parent {
 private String c_3;
}
  • 장점
    • 서브 타입을 구분해서 처리할 때, 효과정
    • not null 제약조건을 사용
  • 단점
    • 여러 자식 테이블을 함께 조회할 때, 성능이 느려짐
    • 자식 테이블을 통합해서 쿼리하기 어려움
  • 특징
    • 구분 컬럼을 사용 ❌

2. @MappedSuperclass

@MappedSuperclass
public abstract class Base {
 private String name;
 private Long price;
 ...
}
@Entity
public class Child_1 extends Base {
 private Long id;
 private String c_1;
 ...
}
@Entity
public class Child_2 extends Base {
 private Long id;
 private String c_2;
 private String c_22;
}
@Entity
public class Child_3 extends Base {
 private Long id;
 private String c_3;
}
  • 부모 클래스는 테이블 매핑 ❌, 자식 클래스에게 매핑 정보만 제공!
    -> @MappedSuperclass
  • @MappedSuperclass를 비유하자면 추상클래스와 비슷
    -> 매핑 정보를 상속할 목적으로만 사용
profile
Backend Developer

0개의 댓글