[본 포스팅은 자바 ORM 표준 JPA 프로그래밍 기본 편을 기반으로 작성하였습니다.]
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런
www.inflearn.com
주요 애노테이션
- @Inheritance(strategy=InheritanceType.XXX) - 부모 클래스에 선언
- JOINED: 조인 전략
- SINGLE_TABLE: 단일 테이블 전략
- TABLE_PER_CLASS: 구현 클래스마다 테이블 전략
- @DiscriminatorColumn(name=“DTYPE”) - 부모 클래스에 선언
- DB에 저장될 때 Item 테이블에 새로운 칼럼으로 저장된 자식 테이블 이름 또는 설정한 값이 들어간다.
- @DiscriminatorValue(“XXX”) - 자식 클래스에 선언
- 부모 클래스에서 DTYPE으로 어떤 값을 넣어줄지 정하는 것이고 기본적으로는 자신의 테이블 이름으로 설정된다.
시나리오)
- 사용자가 음반, 영화, 책 중 음반을 구매하였다.
- DB에는 우측 사진과 같이 Item과 앨범 테이블에 구매 이력을 넣는다.
상속관계 전략
- 각각 테이블로 변환 -> 조인 전략(기본적)
- 통합 테이블로 변환 -> 단일 테이블 전략
- 서브타입 테이블로 변환 -> 구현 클래스마다 테이블 전략(비추천)
조인 전략(기본적)
조인전략의 경우 위 사진처럼 아이템이라는 부모 테이블이 있고,
ALBUM, MOVIE, BOOK 클래스를 나눠서 저장한다.
자식 테이블의 부모 PK를 FK로 물려받고 그것이 PK가 된다.
- 장점
- 테이블 정규화
- 외래 키 참조 무결성 제약조건 활용 가능
- 저장공간 효율화
- 단점
- 조회 시 조인을 많이 사용, 성능 저하
- 조회 쿼리가 복잡함
- 데이터 저장 시 INSERT SQL 2번 호출(성능에 크게 영향 없음)
코드
- Item.class
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
- Book.class
@Entity
public class Book extends Item {
private String author;
private String isbn;
}
조인 전략의 경우 클래스에 아래처럼 애노테이션을 붙여주면 된다.
@Inheritance(strategy = InheritanceType.JOINED)
그리고 자식 클래스는 extends를 받아주면 된다.
그 외 Album, Movie 클래스도 동일한 방식으로 해주면 된다.
데이터를 저장한 후 테이블
DiscriminatorColumn, DiscriminatorValue("M") 적용 시
단일 테이블 전략
DB 설계 시 단순하고 확장성도 크게 없다면 단일 테이블 전략도 괜찮은 방법이다.
- 장점
- 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
- 조회 쿼리가 단순함
- 단점
- 자식 엔티티가 매핑한 칼럼은 모두 null 허용
- 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다.
상황에 따라서 조회 성능이 오히려 느려질 수 있다.
코드
코드의 경우 자식 클래스는 변경 안 해도 되고 Item(부모) 클래스에서
기존에 Inheritance를 아래와 같이 변경해주면 된다.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
- Item.class
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
데이터를 저장한 후 테이블
고객이 영화만 구매했을 경우 ALBUM과 MOVIE 관련 칼럼은 비어있는 것을 확인할 수 있다.
구현 클래스마다 테이블 전략(비추천)
※ 이 전략은 추천하지 않는다.
- 장점
- 서브 타입을 명확하게 구분해서 처리할 때 효과적
- not null 제약조건 사용 가능
- 단점
- 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
- 자식 테이블을 통합해서 쿼리 하기 어려움
코드
코드의 경우 자식 클래스는 변경 안 해도 되고 Item(부모) 클래스에서
기존에 Inheritance를 아래와 같이 변경해주면 된다.
참고로 @DiscriminatorColumn과 @DiscriminatorValue는 필요가 없어지게 된다.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
- Item.class
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
데이터를 저장한 후 테이블
Item 테이블은 생성이 되지 않고 위와 같이 Movie 테이블에만 저장이 된다.
'JAVA > JPA' 카테고리의 다른 글
[JPA] 스프링 데이터 JPA 페이징과 정렬 (feat. DTO를 사용해야 하는 이유) (0) | 2023.01.02 |
---|---|
[JPA/JPQL] 페치 조인(fetch join)이란? 특징과 한계 - 엔티티 페치 조인, 컬렉션 페치 조인, DISTINCT로 중복 제거 (0) | 2022.12.29 |
[JPA] @MappedSuperclass로 공통 칼럼 상속받기 (0) | 2022.12.23 |
[JPA] 다대일(N:1), 일대다(1:N), 일대일(1:1) 연관관계 매핑 (코드 예시) (0) | 2022.12.23 |
[JPA] 엔티티 매핑(@어노테이션)과 스키마 자동 생성 속성 (0) | 2022.12.20 |