관계형 데이터베이스는 객체의 상속 개념이 없다. 대신 슈퍼타입 - 서브타입 모델링 기법을 사용한다. JPA에서는 이를 상속관계 매핑을 통해 지원함.
1. 슈퍼타입 - 서브타입 논리 모델을 물리 모델로 변환하는 방법
조인 전략 (일단 조인 전략을 기본으로 선택!)
- 여러 테이블로 나누어 저장하고 JOIN을 통해 데이터를 조회하는 전략입니다.
- 장점
- 테이블이 정규화되어 데이터 중복이 없다.
- 외래 키 참조 무결성 제약조건 활용 가능
- 저장공간 효율화
- 단점
- 조회시 JOIN 연산이 많이 사용, 성능 저하
- 조회 쿼리가 복잡함
- 데이터 저장시 INSERT SQL 2번 호출하지만, 큰 성능 문제는 아님.
- 예시 코드(조인 전략)
- 장점
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // 조인 전략
@DiscriminatorColumn(name = "DTYPE") // 구분 컬럼 추가
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
}
@Entity
@DiscriminatorValue("BOOK")
public class Book extends Item {
private String author;
}
@Entity
@DiscriminatorValue("MOVIE")
public class Movie extends Item {
private String director;
}
- 조인 전략 설명
- 부모 클래스인 Item의 공통 속성은 Item 테이블에 저장
- 자식 클래스 Book과 Movie의 고유 속성은 각각 Book 테이블과 Movie 테이블에 저장된다.
- 조회 시 JOIN을 통해 데이터를 합쳐서 가져온다.
단일 테이블 전략(SINGLE _TABLE)
- 하나의 테이블에 모든 데이터를 저장하는 전략
- 장점
- JOIN이 필요 없으므로 조회 성능이 빠르다.
- 조회 쿼리가 단순하다.
- 단점
- 자식 엔티티에 매핑된 컬럼은 null 값을 허용해야 해서 치명적이다.
- 하나의 테이블에 모든 데이터를 저장하므로 테이블이 커질 수 있다.
- 예시 코드(단일 테이블 전략)
import jakarta.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 단일 테이블 전략
@DiscriminatorColumn(name = "DTYPE") // 구분 컬럼 추가
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
}
@Entity
@DiscriminatorValue("BOOK")
public class Book extends Item {
private String author;
}
@Entity
@DiscriminatorValue("MOVIE")
public class Movie extends Item {
private String director;
}
- 단일 테이블 전략 설명
- 하나의 테이블(Item)에 부모와 자식 엔티티의 모든 데이터를 저장한다.
- DTYPE 컬럼을 통해 각 행이 어떤 엔티티인지 구분한다.
- 사실 전략을 바꿀 때는 그냥 InheritenceType만 바꿔주면 된다
2. 공통 매핑 정보(MappedSuperclass)
공통된 매핑 정보가 필요할 때 사용한다. 예를 들어, createdAt(생성일), updatedAt(수정일) 같은 공통 필드가 필요하면 @MappedSuperclass를 활용하면 된다.
- 특징
- 엔티티가 아니며 테이블과 매핑되지 않는다.
- 자식 엔티티에 공통 매핑 정보만 제공
- 조회, 검색 불가하므로 추상 클래스로 만드는 것이 일반적
@Getter
@MappedSuperclass // 공통 매핑 정보 제공
@EntityListeners(AuditingEntityListener.class) // 자동 날짜 설정
public abstract class BaseEntity {
@CreatedDate
@Column(updatable = false)
private LocalDate createdAt;
@LastModifiedDate
private LocalDate updatedAt;
}
@Entity
public class Product extends BaseEntity {
@Id @GeneratedValue
private Long id;
private String name;
}
- BaseEntity는 공통된 필드인 createdAt과 updatedAt을 제공한다.
- Product 엔티티는 BaseEntity를 상속 받아 공통 매핑 정보를 사용한다.
3. 주요 애너테이션 정리
- @Inheritance(strategy = InheritanceType.XXX)
- 상속관계 매핑 전략을 지정합니다.
- JOINED: 조인 전략
- SINGLE_TABLE: 단일 테이블 전략
- 상속관계 매핑 전략을 지정합니다.
- @DiscriminatorColumn(name = "DTYPE")
- 구분 컬럼을 추가하여 각 행이 어떤 엔티티인지 구분합니다.
- @DiscriminatorValue("XXX")
- 각 자식 엔티티의 구분 값을 설정합니다.
- @MappedSuperclass
- 공통 매핑 정보를 제공할 때 사용합니다.
'Back-End > JPA' 카테고리의 다른 글
| Spring DataJpa : 쿼리 메서드 기능 (0) | 2024.12.18 |
|---|---|
| 프록시와 연관관계 관리(JPA) (0) | 2024.12.17 |
| JPA 연관관계 Mapping(2) (0) | 2024.12.14 |
| JPA 데이터베이스 스키마 자동 생성과 주의점 (1) | 2024.12.13 |
| JPA 연관관계 Mapping (0) | 2024.12.10 |