아래는 다대다 관계인 Category 와 Item 의 외래키들을 저장할 중간 테이블이 추가되었다.
(다대다는 가급적 비추!! 예시니깐 사용해 보는 것! feat.김영한 개발자님)
Category 가 List<Item>
을 가지고, Item 은 List<Categories>
를 가지는 것을 볼 수 있음.
이런식으로 하면 되는데, 코드는 생략하겠음.
객체의 상속관계와 비슷한 모델링 기법이 있음.
슈퍼타입 서브타입
상속관계 매핑 : 객체의 상속 구조와 DB의 슈퍼타입 서프타입 관계를 매핑
(덧) DiscriminatroColumn 어노테이션이 있어야, DTYPE 생김
-> DiscrimatorValue로 값 지정 가능!
Item.java
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
Album.java
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
}
Book.java
@Entity
@DiscriminatorValue("B")
public class Book extends Item{
private String author;
private String isbn;
}
Movie.java
@Entity
@DiscriminatorValue("M")
public class Movie extends Item{
private String director;
private String actor;
위 그림 처럼 3개의 테이블 + Item 의 테이블 (DTYPE이 있는) 이 생성된다!
Item.java 의 annotation 만 바꾸어주면 된다
@Entity
// @Inheritance(strategy = InheritanceType.JOINED)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
(덧) DiscriminatroColumn 어노테이션이 없어도 DTYPE 생김
위 그림처럼 하나의 테이블에 모든 변수들이 Column 으로 담겨 있는 것을 알 수 있다.
엄청나지 않은가? 어노테이션 하나 바꾸면, 상속 관련 테이블 전략이 한방에 바뀜...
@Entity
// @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
//@DiscriminatorColumn
(덧) 여기서 Item 이 abstract class 가 아니면, Item table은 만들어짐.
<장점>
데이터가 정규화 되어 있음
외래키 참조 무결성 제약조건 활용가능
저장공간 효율화
<단점>
조회시 조인 많이 사용
조회 쿼리 복잡
데이터 저장시 insert sql 2번 호출
<장점>
조회 성능이 빠름
조회 쿼리가 단순
<단점>
자식 엔티티가 매핑한 컬럼은 모두 null을 허용해줘야함
테이블이 커질 수 있고, 조회 성능이 오히려 느려질 수 있음
-> 왠만하면 쓰지 마라.
데이터베이스 설계자들 도 싫어하고, ORM 전문가들도 싫어하는!! 방식
조인 이나 단일테이블 중에 골라서 하면 된다!!
공통적으로 자주 쓰이는 것들. 엔티티 마다 필요한 값들 (ex. 생성시간, 수정 시간 등)
추상클래스로 사용하는 것을 추천!!
@MappedSuperclass
public abstract class BaseEntity {
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
}
기존 사안에 추가로,