반응형
Intro
관계형 데이터베이스에서는 기본적으로 상속 관계를 지원하지 않는다.
JPA에선 이런 문제를 해결해줄 수 있는 3가지 상속관계 매핑 방법을 지원한다.
이번 시간엔 JPA를 통해 상속 관계를 매핑하는 방법에 대해 알아보자.
실습하기 전 아래의 간단한 테스트용 Entity 2개를 만들어보자.
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Book extends Item {
private String author;
private String isbn;
}
주요 어노테이션
상속관계 매핑에는 3가지의 어노테이션이 사용된다.
- @Inheritance(strategy=InheritanceType.XXX): 상속관계 매핑 방법을 선택한다.
JOINED, SINGLE_TABLE, TABLE_PER_CLASS 3가지 중에서 하나를 선택할 수 있다. - @Discrimintaorcolumn(name="DTYPE"): 부모 클래스에서 자식 클래스를 구분하는 컬럼의 이름을 설정한다.
- @DiscriminatorBalue("XXX"): 자식 클래스를 식별하기 위해 부모의 DTYPE 컬럼에 저장될 값을 설정한다.
기본 값은 클래스 이름이다.
JOINED 전략
특징
- 가장 추천하는 방법이다.
- 부모 및 자식 클래스가 정의된 그대로 만들어진다.
- 부모 클래스엔 자식 클래스 구분을 위한 DTYPE, 자식 클래스엔 JOIN을 위한 ITEM_ID 컬럼이 생성된다.
장점
- 테이블이 정규화 되어있다.
- 필요없는 데이터를 저장하지 않아 저장공간을 효율적으로 사용할 수 있다.
단점
- 테이블이 분리되어있어 조회 시 JOIN을 많이 사용해야 하기 때문에 복잡하고 성능이 저하된다.
- 테이블이 분리되어있어 INSERT 쿼리를 2번씩 호출해야 한다.
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@DiscriminatorValue("BOOK")
public class Book extends Item {
private String author;
private String isbn;
}
SINGLE_TABLE 전략
특징
- 자식 클래스의 모든 속성들을 다 부모 클래스에 때려넣은 테이블을 생성한다.
- 서비스 규모가 크지 않아 단순하게 해도 상관 없을 때 사용하기 좋다.
장점
- JOIN이 필요없어 보통 조회 성능이 잘 나온다.
- INSERT 시 쿼리가 1번만 나간다.
단점
- 자식 클래스의 속성들은 모두 NULL을 허용해야 한다.
- 자식 클래스의 속성이 많으면 많아질수록 테이블의 크기가 커진다.
이런 경우 저장공간이 낭비되고, 조회 성능이 오히려 느려질 수 있다.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@DiscriminatorValue("BOOK")
public class Book extends Item {
private String author;
private String isbn;
}
CLASS_PER_TABLE 전략
특징
- SINGLE_TABLE과 반대로 모든 자식 클래스에 부모 클래스의 속성을 때려넣는다.
- 단점이 크기 때문에 추천하지 않는다.
장점
- 서브 타입을 명확하게 구분해서 처리할 수 있다.
- 컬럼에 NOT NULL 제약조건을 설정할 수 있다.
단점
- 여러 자식 테이블을 함께 조회할 때 UNION을 사용해야 해서 성능이 느리다.
- 자식 테이블을 통합해서 쿼리하기 힘들다.
- 자식 클래스가 추가되면, 조회 코드를 변경해야 한다.
- 쓰지 말자.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "DTYPE")
public class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@DiscriminatorValue("BOOK")
public class Book extends Item {
private String author;
private String isbn;
}
출처
반응형
'Study > JPA' 카테고리의 다른 글
[JPA] 공통 속성 매핑 (0) | 2022.08.26 |
---|---|
[JPA] 연관관계 매핑 (0) | 2022.08.25 |
[JPA] Entity 필드, 컬럼 매핑 (0) | 2022.03.05 |
[JPA] 영속성 컨텍스트 (0) | 2022.03.05 |
[JPA] DB에 데이터 넣어보기 (0) | 2022.02.26 |