상속관계 매핑

 

 

관계형 DB에서는 상속관계라는 개념이 존재하지 않는다.

RDB에는 슈퍼타입 서브타입 관계라는 모델링 기법이 존재하는데 이 개념이 상속과 유사한 점이 있다. 

 

 

슈퍼타입 서브타입 관계

 

1. 각각 테이블로 변환 --> 조인 전략

2. 통합 테이블 변환 --> 단일 테이블 전략

3. 서브타입 테이블로 변환 ==> 구현 클래스마다 테이블 전략

 

 

1. 조인전략 (가장 많이 사용)

 

item(물품)이라는 공통 키워드를 통해 각 테이블을 나누고 공통요소를 묶어서 조인을 통해 조회하거나 관리

(DTYPE: 앨범테이블인지 무비테이블인지 구분하는 구분자 컬럼)

 

 

@Entity
@Inheritance(stategy = InheritanceType.JOINED) //상속관계 매핑 전략
public class Item{

	@Id @GeneratedValue
    private Long id;
    
    private String name;
    
    private int price;
    
}


@Entity
public class Album extends Item {
	private String artist;
}

@Entity
public class Movie extends Item {
	private String director;
    private String actor;
    
}

@Entity
public class Book extends Item {
	private String author;
    
}

 

만약 Book find = em.find(Book.class, book.getId()); 이렇게 조회를 할때 쿼리가 자동으로 item테이블과 조인된 쿼리가 나가게 된다.

 

ex: item엔티티에 @DiscriminatorColumn 어노테이션을 넣어주면 DTYPE(구분가능한 구분자) 컬럼이 추가된다.

 

자식 엔티티에는 @DiscriminatorValue(name="A") 이런식으로 넣어주면 된다.  //name은 내가 원하는 컬럼명

 

- 단점 : 

1. 조인 쿼리라도 성능 저하가 있을 수도 있음.

2. insert 쿼리가 2개가 나간다.  

 

 

2. 단일 테이블 전략

 

 

하나의 테이블에 다 통합해서 관리한다.

 

@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 로 변경하면 된다. 

 

 

- 단점: 

1. 테이블 하나의 모든 데이터를 저장하므로 테이블이 비대해져서 조회 성능이 떨어질 수 있다.

2. 자식 엔티티가 매핑한 컬럼은 모두 NULL 이 될 수 있다.

 

 

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

 

 

모든 테이블마다 값을 각각 소유한다. 

 

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 로 변경해주면 된다.

 

근데 item 엔티티를 추상클래스(abstract)로 만들어줘야 테이블이 안생긴다 (속성들만을 상속).

 

- 단점: 

 1. 자식 테이블을 관련지어서 조회할때 조인이 불가능하고 UNION 쿼리를 통해 조회해야된다.

(성능이 느리다.)

 

2. 자식 테이블들이 서로 관련이 없어서 통합 쿼리를 작성하기 어려움 

 

 

@MappedSupperclass

얘는 상속관계매핑이랑 크게 관련은 없다.

그냥 단지 공통 매핑 정보가 필요할때 한곳에서 관리하려고 선언된다. 

 

등록일자, 수정일자 ,등록자 등 모든테이블에서 공통으로 있는 컬럼이 있을때 사용

 

@MappedSuperclass
public abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    // Getter와 Setter 생략
}

@Entity
@Table(name = "users")
public class User extends BaseEntity {

    private String name;
    private String email;

    // Getter와 Setter 생략
}

 

BaseEntity 클래스는 직접 사용되는 일이 없으므로 추상클래스로 선언되어도 무방하다.

Users엔티티는 BaseEntity를 상속하여 공통 데이터를 관리 가능하다.

 

 

 

 

자료 참고:  해당 자료는 김영한 강사님의 JPA 강의를 참고하였습니다.

 

https://www.inflearn.com/users/74366/@yh

 

김영한님의 소개 - 인프런 | 온라인 강의 플랫폼

인프런 김영한님의 소개 페이지 입니다. - 김영한님 소개 | 인프런

www.inflearn.com

 

 

'JPA' 카테고리의 다른 글

[JAVA]JPA_즉시로딩과 지연로딩  (0) 2024.10.30
[JAVA] JPA_연관관계  (0) 2024.10.27
[JAVA] JPA_연관관계 매핑  (0) 2024.10.27
[JAVA] JPA_영속성 관리  (0) 2024.10.18
[JAVA] JPA란?  (0) 2024.10.18

+ Recent posts