Spring Boot/JPA

[JPA] 연관관계 매핑 - 상속관계 매핑, @MappedSuperclass

공대생안씨 2023. 12. 18. 14:26

 

연관관계 매핑 관련 게시물

2023.12.18 - [JPA] - [JPA] 연관관계 매핑 - 단방향 매핑, 양방향 매핑

2023.12.18 - [JPA] - [JPA] 연관관계 매핑 - 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)

 

상속관계 매핑

 

관계형 데이터베이스에는 상속관계가 존재하지 않는다. 대신 슈퍼타입, 서브타입이 존재하는데 이를 객체의 상속관계로 풀어내는 매핑이다.

공통 어노테이션

  • @Inheritance(strategy = InheritanceType.XXXX)
  • @DiscriminatorColumn(name = "구별자 컬럼 이름")
  • @DiscriminatorValue("구별자 값")

슈퍼타입, 서브타입 논리 모델
엔티티

 

상속관계 매핑 - 조인 전략

서브타입에 해당하는 Album, Book, Movie 모두 테이블로 변환

DTYPE (구별자) 속성을 상위 테이블에 추가하여 하위 테이블을 구분

조인 전략

// Item 클래스
@Entity
@Inheritance(strategy = InheritanceType.JOINED)	// 조인전략
@DiscriminatorColumn(name = "DISCRIMINATOR")	// 구별자 컬럼 이름 지정 (기본값 : "DTYPE")
public class Item{
	// 필드 작성
}
// Album, Book, Movie 엔티티
@Entity
@DiscriminatorValue("A")	// DTYPE의 값 설정 (기본값 : 엔티티 이름 그대로 (Album))
public class Album extends Item{
	// 필드 작성
}

 

MySQL 결과 => 각각 테이블이 생성됨을 확인

Item, Album, Book, Movie 테이블
Item 테이블
Album 테이블
Book 테이블
Movie 테이블

 

상속관계 매핑 - 단일 테이블 전략

서브 타입에 해당하는 Album, Book, Movie 모두 Item 테이블에 속성으로 추가

해당 카테고리의 값이 아닌 속성은 null로 삽입

구별이 필요하므로 DTYPE 필수 (@DiscriminatorColumn 어노테이션을 안 써도 자동으로 삽입됨)

단일 테이블 전략

// Item 클래스
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)	// 단일 테이블 전략
//@DiscriminatorColumn(name = "DISCRIMINATOR")	// 구별자 컬럼이 자동으로 생성됨
public class Item{
	// 필드 작성
}

 

MySQL 결과 => 서브타입의 엔티티는 테이블이 생성되지 않음, Item 테이블에 모든 속성 추가됨

Item 테이블만 존재
Item 테이블

 

상속관계 매핑 - 구현 클래스마다 테이블 전략

슈퍼 타입에 해당하는 Item 엔티티의 속성이 모두 서브 타입에 해당하는 엔티티에 내려감

Item 클래스를 독단적으로 사용할 일 없으므로 추상 클래스로 구현

@DiscriminatorColumn 이 의미 없음 (넣어도 구별자 컬럼 추가 안됨)

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

// Item 클래스
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)	// 구현 클래스마다 테이블 전략
//@DiscriminatorColumn(name = "DISCRIMINATOR")	// 사용 불가
public abstract class Item{	// 추상 클래스로 구현
	// 필드 작성
}

 

MySQL 결과 => Item 테이블 생성 안됨, 하위 테이블에 각각 Item 엔티티의 속성이 추가됨

Album, Book, Movie 테이블만 생성
Album 테이블 : Item의 속성 내려옴
Book 테이블 : Item의 속성 내려옴
Movie 테이블 : Item의 속성 내려옴

 

 

@MappedSuperClass

 

여러 테이블에 공통으로 존재하는 속성이 있다면 이를 하나의 클래스(BaseEntity)로 구현하고 해당 클래스를 여러 테이블이 상속받는 방식

상속관계 매핑이 아니고 속성을 공통으로 사용하고 싶을 때 사용함

부모 클래스를 상속받는 자식 클래스에 매핑 정보만 제공 => (엔티티가 아니므로) BaseEntity 테이블은 생성되지 않음

조회 불가 (em.find(BaseEntity.class, ~); 불가)

직접 생성할 일 없으므로 추상 클래스로 구현

@MappedSuperClass

// BaseEntity 클래스 (엔티티가 아니므로 @Entity 어노테이션 X)
@MappedSuperclass   // 매핑 정보만 받는 슈퍼 클래스 (부모 클래스)
public abstract class BaseEntity {  // 직접 생성해서 쓸 일 없으므로 추상 클래스로 구현
	// 필드 구현
}
// Member, Seller 엔티티
@Entity
public class Member extends BaseEntity{	// BaseEntity 클래스에 저장된 공통 속성을 상속받음
	// 필드 구현
}