✅ 상속관계 매핑
상속
관계라는 것이 없음슈퍼타입 서브타입의 관계
가 자바의 객체 상속이라 비슷함
왼쪽 그림은 자바의 상속 상태를 나타내며
오른쪽 그림에서 Item은 슈퍼타입 Album, Movie, Book 은 서브타입을 의미한다
✅ 상속관계 매핑 방법 3가지
슈퍼타입 서브타입 논리 모델을 실제 물리모델로 구현하는 방법 3가지
조인 전략
: 각각 테이블로 변환하는 방법으로 기본적으로 많이 사용함단일 테이블 전략
: 통합 테이블로 변환구현 클래스마다 테이블 전략
: 서브타입 테이블로 변환위 3가지의 전략을 사용하기 위해서는 다음과 같은 어노테이션 필요하다
@Inheritance(strategy=InheritanceType
.XXX
어노테이션을 사용하지 않으면 기본적으로 JPA는 단일 테이블 전략
이 적용됨
XXX 에는 각 전략에 따라 명칭이 달라진다
JOINED : 조인 전략
SINGLE_TABLE : 단일 테이블 전략
TABLE_PER_CLASS : 구현 클래스마다 테이블 전략
@DiscriminatorColumn
: 자식 테이블들을 구별할 수 있는 DTYPE
이라는 컬럼이 생김
기본 값은 DTYPE으로 명칭을 바꾸고 싶으면 -> @DiscriminatorColumn(name = "")
-> name 안에 명칭
조인 전략에서는 이 어노테이션을 사용하는 것이 편하다
하지만 단일 테이블 전략에서는 이 어노테이션이 필수 -> 없으면 구별할 수 없음
@DiscriminatorValue(“XXX”)
자식클래스에서 사용하는 것으로 @DiscriminatorColumn
컬럼 안에 구분되는 값이 들어갈 때 사용
어노테이션을 사용하지 않으면 기본값으로 해당 자식 객체의 Entity 값이 들어감
어노테이션을 사용하면 XXX 값에 원하는 명칭으로 변경 가능
✅ 조인 전략
장점
단점
조인
을 많이 사용해서 성능이 저하 = 조회 쿼리가 복잡@Entity
@Inheritance(strategy = InheritanceType.JOINED) // 조인 전략
public class Item{
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@Entity
public class Album extends Item {
private String artist
}
@Entity
public class Movie extends Item {
private String director;
private String actor;
}
@Entity
public class Book extends Item {
private String author;
private String isbn;
}
// main함수
Movie movie = new Movie();
movie.setDirector("최최최");
movie.setActor("김김김");
movie.setName("박박박"); // 부모 컬럼을 사용
movie.setPrice("5000"); // 부모 컬럼을 사용
em.persist(movie) // persist() 호출하면 조인 할 수 있는 상태로 값이 추가됨
em.flush(); // 영속성 컨텍스트에 있는 것들을 DB안에 다 넣기
em.clear(); // 영속성 컨텍스트 초기화 = 1차 캐시 비워짐
Movie findMovie = em.find(Movie.class, movie.getId()); // Movie와 Item이 조인된 상태로 조회됨
✅ 단일 테이블 전략
장점
단점
NULL
을 허용함 = 데이터 무결성 입장에선 애매함코드는 위 조인전략
코드에서 한부분만 변경하면 된다
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 단일 테이블 전략
✅ 구현 클래스마다 테이블 전략
결론적으로 이 전략은 사용하지 않는 것이 좋다
장점
단점
UNION ALL
로 모든 테이블을 조회하기 때문에 비효율적임✅ 매핑 정보 상속
@MappedSuperClass
추상클래스
로 생성 권장em.find(BaseEntity) 불가
@MappedSuperClass
public class BaseEntity { // 요구 조건들만 따로 클래스를 만들어서 넣음
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
// getter + setter 생략
}
@Entity
public class Member extends BaseEntity { // 위 클래스를 상속받으면 사용 가능
위 Member 코드와 동일
}
✅ @Entity
@MappedSuperclass
차이
위 예시에서 BaseEntity에 @Entity
를 적용시 상속관계로 사용하겠다는 의미 (부모 테이블 조회 수정 가능)
하지만 @MappedSuperclass
를 적용하면 속성
만 상속 받을 때 사용 (부모 테이블 조회 수정 불가능)