관계형 데이터베이스는 상속 관계가 없으며 객체의 상속과 유사한 슈퍼타입과 서브타입이 있다.
슈퍼타입과 서브타입의 논리모델을 실제 물리모델로 구현하는 방법은 크게 3가지가 있다.
1. 각각 테이블로 변환 -> 조인 전략
2. 통합 테이블로 변환 -> 단일 테이블 전략
3. 서브타입 테이블로 변환 -> 구현 클래스마다 테이블 전략
1. 각각 테이블로 변환 -> 조인 전략
슈퍼타입과 서브타입으로 나누어 슈퍼타입에 공통적인 부분을 두고 조인하는 방식으로 객체의 상속과 가장 유사하다.
조회 쿼리가 복잡하지만 저장공간이 효율적이며 테이블 정규화가 가능해진다.
2. 통합 테이블로 변환 -> 단일 테이블 전략
한 테이블에 모두 통합하는방식이다.
조인이 필요 없으므로 일반적으로 조회 성능이 빠르지만 테이블이 너무 커질 수 있다.
자식 엔티티가 매핑한 컬럼은 모두 null 허용해야한다. 다른테이블 정보는 들어오지 않는경우를 위해
3. 서브타입 테이블로 변환 -> 구현 클래스마다 테이블 전략
슈퍼타입이 없이(공통적인부분을 )각각의 서브타입에 넣어주는 방식이다.
조회할 때 성능이 느림으로 추천하지 않는다.
예를들어 item의 아이디가 5번인 정보를 찾으려면 3개의 테이블을 다 뒤져봐야한다..
주요 어노테이션
@Inheritance
주요 어노테이션으로 부모클래스에서 사용하는 @Inheritance이 있다. 이는 위에서 말한 물리모델을 구현하는 방식을 선택해주는 어노테이션으로 종류는 3가지이다.
• JOINED: 조인 전략
• SINGLE_TABLE: 단일 테이블 전략
• TABLE_PER_CLASS: 구현 클래스마다 테이블 전략
사용법
@Inheritance(strategy=InheritanceType.XXX)
@DiscriminatorColumn(name=“DTYPE”)
@DiscriminatorColumn은 슈퍼타입 테이블에 있는 정보가 어느 서브타입의 정보인지를 알려주는 컬럼을 만들어주는 어노테이션이다. 기본값은 DTYPE 이며 이컬럼에 서브테이블의 명칭이 들어간다.
조인전략은 @DiscriminatorColumn을 선언하지 않으면 생성되지않지만
단일테이블 전략은 @DiscriminatorColumn를 선언하지않아도 자동생성된다. 왜냐하면 단일이기때문에 구분이 없으면 어느정보인지 구별할 수 없기 때문이다.
++만약 들어가는 서브테이블의 명칭을 변경하고 싶다면
@DiscriminatorValue(“XXX”)을 자녀 클래스에 선언해주면 된다.
@MappedSuperclass
MappedSuperclass는 공통 매핑 정보가 필요할 때 사용한다.
중요한건 상속관계 매핑이 아니라는 점!
이는 객체의 부모클래스에 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공한다는걸 선언해준다.
1.조회, 검색 불가(em.find(BaseEntity) 불가)하며
2.엔티티가 아니고, 테이블과 매핑이 아니다.
3. 직접 생성해서 사용할 일이 없으므로 추상 클래스를 권장한다.
(ex. public abstract class BaseEntity)
때문에@MappedSuperclass를 사용하는 클래스는 테이블과 관계가 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다고 생각하면된다.
- 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통 으로 적용하는 정보를 모을 때 사용하며
- @Entity 클래스는 엔티티나 @MappedSuperclass로 지 정한 클래스만 상속 가능