상속은 객체지향에는 존재하지만 관계형DB에는 존재하지 않는다. 관계형 DB에서 상속관계는 슈퍼타입 - 서브타입
를 사용하면 비슷하게 구현 가능하다.
가령 위와 같은 상속관계를 가진 엔티티가 있다고 생각해보자. 위 관계도는 판매물품의 공통부분은 Item으로 묶고 나머지 속성을 서브클래스로 상속받은 관계도인데 코드는 다음과 같이 작성한다.
# Item Class
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item {
}
# 하위 Class
@Entity
public class Album extends Item{
}
OOP의 상속코드랑 다를게 하나 없다. 여기서 주목해야 할 부분은 @Inheritance
과 @DiscriminatorColumn
두가지다.
@Inheritance는 상속관계 엔티티를 DB에 어떤 전략으로 표현할지 설정하는 어노테이션 이다. 기본적으로 단일 테이블 전략을 채택하였다.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)으로 설정.
사진에 색칠한 컬럼을 보면 Album, Book, Movie 엔티티로 나눠서 관리하는 데이터를 한 테이블에 넣고 필요에 따라 채워서 사용하는 방식이다.
@Inheritance(strategy = InheritanceType.JOINED)
조인 전략은 슈퍼타입 - 서브타입 관계로 상속관계 비슷한 모양새인데 조인을 사용하여 데이터를 조회하는 방법이다.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
이 전략은 각 하위 엔티티를 각각 테이블로 만들어 사용하는 전략으로 공통된 속성 역시 각각 테이블에서 관리한다. 하지만 데이터지향 관점으로 보나, 객체지향 관점으로 보나 어느 쪽도 추천하지 않는 방식이다.
@DiscriminatorColumn 어노테이션은 자식 타입을 명확하게 구분해주는 컬럼인데 단일 테이블 전략, 조인 전략에 보면 DTYPE 컬럼을 만들어 주는 어노테이션이다.
DTYPE 컬럼에 Movie, Book, Album 같이 표현해줌으로 어떤 타입의 데이터인지 편하게 구분하도록 도와주는 것 이다.
@DiscriminatorColumn은 기본 DTYPE 컬럼을 생성하도록 되어있으며 name
속성 값으로 컬럼명을 변경할 수 있다. 또한 하위 타입명은 기본적으로 Entity명으로 작성이 되는데 하위 엔티티에 @DiscriminatorValue("컬럼 벨류")를 사용하여 타입값을 변경 할 수 있다.