참고
해당 글은 김영한님의 자바 ORM 표준 JPA 프로그래밍을 공부하며 작성한 글입니다.
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
상속관계 매핑
자바 객체에는 상속 관계가 존재하지만, 관계형 데이터베이스에서는 상속 관계가 없다.
데이터적으로 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속과 유사하여 객체의 상속관계 매핑에 사용한다.
상속 관계 매핑을 구현하는 3가지 방법
- 각각 테이블로 변환 → 조인 전략
- 통합 테이블로 변환 → 단일 테이블 전략
- 서브타입 테이블로 변환 → 구현 클래스마다 테이블 전략
주요 어노테이션
@Inheritance(strategy=InheritanceType.XXX)
- JOINED : 조인 전략
- SINGLE_TABLE : 단일 테이블 전략
- TABLE_PER_CLASS : 구현 클래스마다 테이블 전략
@DiscriminatorColumn(name=”DTYPE”)
- DTYPE 컬럼명을 변경한다. 기본값 = DTYPE
@DiscriminatorValue(”XXX”)
- 자식클래스에서 DTYPE에 들어갈 값을 설정한다. 기본값 = 엔티티 명
조인 전략
DTYPE으로 ALBUM인지, MOVIE인지, BOOK인지 구분한다.
장점
- 테이블 정규화
- 외래 키 참조 무결성 제약조건 활용가능
- 저장공간 효율화
단점
- 조회시 조인을 많이 사용, 성능 저하
- 조회 쿼리가 복잡함
- 데이터 저장시 INSERT SQL 2번 호출
구현 코드
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {
@GeneratedValue
@Id
private Long id;
private String name;
private int price;
}
@Entity
public class Movie extends Item{
private String director;
private String actor;
}
부모 클래스에는 @Inheritance
, @DiscriminatorColumn
어노테이션을 이용하고, 자식클래스에서는 상속만 받으면 된다.
단일 테이블 전략
조인을 해서 데이터를 가져오지않고, 하나의 테이블에 자식 엔티티와 부모 엔티티의 컬럼을 매핑한다.
장점
- 조인이 필요없기 때문에 일반적으로 조회 성능이 빠르다.
- 조회 쿼리가 단순하다.
단점
- 자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 한다.
- 단일 테이블에 모든 것을 저장하여 테이블이 커질수 있으며, 이에 따라 조인하는것 보다 조회성능이 느려질 수 있다.
구현 코드
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public class Item {
@GeneratedValue
@Id
private Long id;
private String name;
private int price;
}
조인 전략과 마찬가지로 부모 클래스에 @Inheritance
어노테이션을 이용하고 타입을 SINGLE_TABLE로 사용한다.
단일 테이블 전략에서는 @DiscriminatorColumn
어노테이션을 생략해도 DTYPE이 자동 생성 된다. (없으면 데이터 구분이 불가능하기 때문)
구현 클래스마다 테이블 전략
부모 클래스인 ITEM 테이블을 없애고, 자식 엔티티의 name, price 같은 공통 컬럼들을 자식 테이블에 허용하는 전략이다.
해당 전략은 데이터베이스 설계자와 ORM 전문가적 시점 둘 다 추천하지 않는다.
장점
- 서브 타입을 명확하게 구분해서 처리할 때 효과적
- not null 제약조건 사용 가능
단점
- 여러 자식 테이블을 함께 조회할 때 성능이 느림
- 자식 테이블을 통합해서 쿼리하기 어려움