본문 바로가기
JAVA/JPA

인프런 JPA 7화 고급 매핑 "김영한 강사" -PlusUltraCode-

by PlusUltraCode 2024. 7. 20.

상속관계 매핑

데이터베이스에서 상속 관계를 매핑하는 방법에는 여러 가지가 있습니다. 이 포스트에서는 Item이라는 엔티티를 예시로 들어 상속 관계를 어떻게 매핑할 수 있는지 살펴보겠습니다. Item 엔티티는 Book, Movie, Album 등으로 확장될 수 있습니다.

상속 관계 매핑 전략

상속 관계를 매핑하는 3가지 주요 전략이 있습니다:

1. 조인 전략 (Joined Strategy)

가장 많이 사용되는 전략으로, Item 엔티티에 DTYPE을 추가하여 구분합니다. 각각의 서브 클래스(Book, Movie, Album)는 별도의 테이블을 가지며, Item 테이블과 조인하여 데이터를 가져옵니다.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
    @Id @GeneratedValue
    private Long id;
    private String name;
    // 기타 공통 속성
}

@Entity
@DiscriminatorValue("B")
public class Book extends Item {
    private String author;
    // 기타 책 관련 속성
}

@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
    private String director;
    // 기타 영화 관련 속성
}

2. 단일 테이블 전략 (Single Table Strategy)

모든 상속 관계를 하나의 테이블에 저장하는 방법입니다. 간단하지만 테이블이 비대해질 수 있습니다.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
    @Id @GeneratedValue
    private Long id;
    private String name;
    // 기타 공통 속성
}

@Entity
@DiscriminatorValue("B")
public class Book extends Item {
    private String author;
    // 기타 책 관련 속성
}

@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
    private String director;
    // 기타 영화 관련 속성
}

3. 각 테이블 전략 (Table per Class Strategy)

각 서브 클래스마다 독립된 테이블을 만드는 방법입니다. 쿼리 성능이 저하될 수 있습니다.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
    @Id @GeneratedValue
    private Long id;
    private String name;
    // 기타 공통 속성
}

@Entity
public class Book extends Item {
    private String author;
    // 기타 책 관련 속성
}

@Entity
public class Movie extends Item {
    private String director;
    // 기타 영화 관련 속성
}

상속 관계 설정 예시

아래는 Item 클래스를 추상 클래스로 만들어서 상속 관계를 설정하는 예시입니다.

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
    @Id @GeneratedValue
    private Long id;
    private String name;
    // 기타 공통 속성
}

@Entity
@DiscriminatorValue("B")
public class Book extends Item {
    private String author;
    // 기타 책 관련 속성
}

MappedSuperclass

공통된 속성(예: 생성일, 수정일 등)을 여러 엔티티에서 사용해야 할 때, @MappedSuperclass를 사용하여 기본 엔티티를 정의할 수 있습니다.

@MappedSuperclass
public abstract class BaseEntity {
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;

    @PrePersist
    protected void onCreate() {
        createdAt = new Date();
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = new Date();
    }
}

@Entity
public class Book extends BaseEntity {
    @Id @GeneratedValue
    private Long id;
    private String name;
    private String author;
    // 기타 책 관련 속성
}

@MappedSuperclass를 사용하면 기본 엔티티에 정의된 속성과 메서드를 하위 엔티티에서 그대로 사용할 수 있어 코드의 재사용성과 유지보수성이 높아집니다.