관계형 DB에서는 상속관계가 없다.
슈퍼타입, 서브타입 관계라는 모델링 기법이 객체상속과 유사한 기능을 한다.
Item 테이블을 만들고,
각 상품들을 Item 테이블에 매핑하는 전략이다.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private long id;
private String name;
private String price;
private String StockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
///Getter Setter
}
@Entity
public class Album extends Item{
private String artist;
}
이렇게 상속하고 Entity로 만들면 상속을 반영할 수 있는 테이블이 생성된다.
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
}
DType의 이름을 따로 지정하고 싶을때 다음과 같은 어노테이션을 사용한다. Default는 Entity 이름이다.
테이블을 하나로 만드는 전략이다. DType으로 구분만 하고, 나머지는 전부 하나의 테이블에 넣는 방식이다.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
이렇게 Item에 붙는 어노테이션 전략을 바꿔주면, 한 테이블 안에 전부 들어가고, DType이 생성된다.
Item_ID를 각 테이블에 주고 전부 테이블을 만드는 전략이다.
하지만 이는 조회성능이 느리고 통합쿼리가 쉽지 않아서 추천되지 않는다.
• 테이블 정규화
• 외래 키 참조 무결성 제약조건 활용가능
• 저장공간 효율화
• 조회시 조인을 많이 사용, 성능 저하
• 조회 쿼리가 복잡함
• 데이터 저장시 INSERT SQL 2번 호출
• 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
• 조회 쿼리가 단순함
• 자식 엔티티가 매핑한 컬럼은 모두 null 허용
• 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다. 상황에 따라서 조회 성능이 오히려 느려질 수 있다.
• 서브 타입을 명확하게 구분해서 처리할 때 효과적
• not null 제약조건 사용 가능
• 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
• 자식 테이블을 통합해서 쿼리하기 어려움
예를들어 생성시간, 수정시간 같은 공용정보를 다 같이 추가한다고 하자. 이때, 각 테이블마다 이를 추가해서 처리해줄 수도 있지만, 이는 매우 불편하다.
이를 한번에 간편하게 해결해주는 기법이 Mapped Superclass 기법이다.
BaseEntity를 만들고 공통매핑정보를 넣은다음
MappedSuperclass를 사용하면 각 테이블에 전부 들어가게 된다.
하지만 이는 엔티티가 아니다. 테이블이 생성되지 않으며, 조회나 검색이 불가능하다.