DevKim
[JPA] 상속관계 매핑 & MappedSuperclass 본문
관계형 DB는 상속관계가 없지만, 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사하기 때문에
이것을 이용하여 객체의 상속과 구조와 관계를 매핑할 수 있다.
[ JOINED 전략 ]
@Getter @Setter
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
조인 전략을 사용하기 위해 Inheritance를 설정해주었고,
Movie만 임의로 저장해서 확인하니 알맞게 저장된 것을 확인할 수 있다.
@DiscriminatorColumn으로 DTYPE 넣어줌으로써 뭐 때문에 Item 테이블에 들어온건지를 알 수 있다.
(꼭 넣어주는게 운영상 좋다고한다)
만약 회사에서 DBA분이 회사 규칙상 Movie는 M으로 저장해야한다고 하면, @DiscriminatorValue("M")을 Movie클래스에 추가해주어야한다.
Movie movie =new Movie();
movie.setDirector("영화감독");
movie.setActor("공유");
movie.setName("공유의영화");
movie.setPrice(100000);
em.persist(movie);
쿼리 로그를 보기위해,
flush로 db에 저장해주고 1차캐시 모두 지워준뒤 조회하니 inner join이 일어나면서
영화정보를 잘 가져온 것을 확인할 수 있었다.
/*
조회
*/
em.flush();
em.clear();
Movie movie1 = em.find(Movie.class, movie.getId());
System.out.println("movie1 = " + movie1);
tx.commit();
장점은 테이블 정규화에 따른 저장공간이 효율적이고 설계가 깔끔하다.
단점은 조회시 조인을 많이 사용하다보니 성능이 저하될 수 있고(조금..) 조회시 단일 테이블보단 복잡하다.
[ SINGLE_TABLE 전략 ]
단일 테이블은 @DiscriminatorColumn 없이도 DTYPE이 자동으로 생성된다.
[Item]
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Item {
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
[Book]
@Entity
@DiscriminatorValue("B") //DB에 저장될 때 Book은 B로 구분됨
public class Book extends Item {
private String author;
private String isbn;
}
단일 테이블 전략은 장점으론 테이블이 하나이기에 조회 쿼리가 단순하고, 일반적으로 조회 성능이 빠르다.
단점으론, 자식 엔티티가 매핑한 컬럼은 모두 아래와 같이 null을 허용해야하고,
상황에 따라 조회 성능이 오히려 느려질 수 있다.
[ TABLE_PER_CLASS 전략]
구현 클래스마다 각각의 정보를 가지고 있는 전략으로, 단점이 너무 치명적이기때문에 고려할 필요도 없다고한다.
조인 전략을 기본 전략으로 가져가는게 좋고, 정말 단순하고 데이터도 별로 안되면 단일 테이블 전략으로 가져가면된다.
trade off가 있기 때문에 상황에 따라 둘 사이에서 고민하는 것이 좋다고한다.
@MappedSuperclass
만약 누가 테이블을 수정했고, 언제 수정했고, 누가 등록했고..같이 전체 엔티티에서 공통으로 사용하는 정보를 추가해야할 때 모든 곳에 추가하기 번거로우니 BaseEntity를 만들어서 상속 받는 자식 클래스에 매핑 정보만 제공하는 것이다.
단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
@MappedSuperclass
public abstract class BaseEntity {
private String createdBy;
private LocalDateTime createdDate;
}
사용하고 싶은 엔티티에서 extends로 상속 받아서 사용하면 된다.
* 상속관계매핑도 아니고 엔티티도 아니기에 테이블과 매핑되지도 않는다. (테이블과 관계없음)
* 직접 생성해서 사용할 일이 없으므로 추상 클래스로 생성하는 것이 좋다.
참고 강의, 자료 출처
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
'JPA' 카테고리의 다른 글
[JPA] 값 타입 - 기본값 타입, 임베디드 타입, 컬렉션 타입 (0) | 2021.06.23 |
---|---|
[JPA] 프록시와 즉시-지연로딩 & CASCADE , 고아 객체 (0) | 2021.06.22 |
[JPA] 다양한 연관관계 매핑 - N:1/1:N/1:1/N:M (0) | 2021.06.21 |
[JPA] 연관관계 매핑 - 단방향,양방향 연관관계 ,연관관계의 주인 (0) | 2021.06.19 |
[JPA] Entity 매핑 - 객체와 테이블, 필드와 컬럼, 기본키 매핑 (0) | 2021.06.18 |