2021. 2. 9. 15:18ㆍ프로그래밍 언어/Spring Framework
[인프런 김영한] JPA - 상속관계 매핑
해당 글은 인프런 김영한강사님의 영상을 보고 정리한 글입니다.
Spring Boot, Spring Data JPA를 사용해 실습하였습니다.
김영한 인프런 : www.inflearn.com/users/@yh
▣ Goal
1. JPA 기본 전략
2. 조인 테이블 전략
3. 단일 테이블 전략
4. 구현 클래스마다 테이블 전략
▣ 상속관계 매핑
* 관계형 데이터베이스는 상속관계가 없다.
* 상속관계 매핑 : 객체의 상속과 구조와 DB의 슈퍼타입, 서브타입(객체 상속과 유사) 관계를 매핑
* 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법
- 각각의 테이블로 변환 -> 조인전략
- 통합 테이블로 변환 -> 단일 테이블 전략
- 서브타입 테이블로 변환 - 구현 클래스마다 테이블 전략
▣ JPA 기본 조인전략
Item
@Entity
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
Album, Movie, Book
@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;
}
실행 결과
create table item (
dtype varchar(31) not null,
id bigint not null,
name varchar(255),
price integer not null,
artist varchar(255),
author varchar(255),
isbn varchar(255),
actor varchar(255),
director varchar(255),
primary key (id)
)
| JPA 기본전략은 하나의 테이블에 모두 넣는 단일 테이블 전략을 사용하고 있습니다.
▣ JPA 조인전략 - JOINED (조인전략)
※ 테이블 설계시 기본으로 선택하며, 정말 단순하다면 단일 테이블 전략 사용.
Item 수정
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
| Item Table에 @Inheritance(strategy = InheritanceType.JOINED) 전략을 사용했습니다.
IngeritanceType에 JOINED를 사용하게 되면 단일 테이블 전략이 아닌, 조인 테이블 전략을 사용하게 됩니다.
JOINED : 조인전략
SINGLE_TABLE : 단일 테이블 전략
TABLE_PER_CLASS: 구현 클래스마다 테이블 전략
장점
- 데이터가 정규화가 되어 있다.
- 외래키 참조 무결성 제약조건을 사용 가능하다.
- 저장공간이 효율화 됩니다.
단점
- 조회시 조인을 많이 사용합니다.
Insert Data
Movie movie = new Movie();
movie.setDirector("디렉터");
movie.setActor("엑터");
movie.setName("영화이름");
movie.setPrice(10000);
movieRepository.save(movie);
// 조회
System.out.println("=======================");
movieRepository.findById(movie.getId());
실행결과
Hibernate:
create table album (
id bigint not null,
artist varchar(255),
primary key (id)
)
Hibernate:
create table book (
id bigint not null,
author varchar(255),
isbn varchar(255),
primary key (id)
)
Hibernate:
create table item (
id bigint not null,
name varchar(255),
price integer not null,
primary key (id)
)
Hibernate:
create table movie (
id bigint not null,
actor varchar(255),
director varchar(255),
primary key (id)
)
Hibernate:
alter table album
add constraint FKrl4nl1yn7tatob2buih6y9qws
foreign key (id)
references item
Hibernate:
alter table book
add constraint FKqk00l5u7w76kq5n45m9h5t5rj
foreign key (id)
references item
Hibernate:
alter table movie
add constraint FK77hfitoaq24bt17vl2307651e
foreign key (id)
references item
Hibernate:
insert
into
item
(name, price, id)
values
(?, ?, ?)
Hibernate:
insert
into
movie
(actor, director, id)
values
(?, ?, ?)
//조회
Hibernate:
select
movie0_.id as id1_2_0_,
movie0_1_.name as name2_2_0_,
movie0_1_.price as price3_2_0_,
movie0_.actor as actor1_3_0_,
movie0_.director as director2_3_0_
from
movie movie0_
inner join
item movie0_1_
on movie0_.id=movie0_1_.id
where
movie0_.id=?
H2 database
SELECT * FROM ITEM;
ID NAME PRICE
1 영화이름 10000
SELECT * FROM ALBUM;
ARTIST ID
SELECT * FROM BOOK ;
AUTHOR ISBN ID
SELECT * FROM MOVIE ;
ACTOR DIRECTOR ID
엑터 디렉터 1
▣ Dtype
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
| @DiscriminatorColumn을 사용하게 되면 Dtype에 INSERT된 TABLE 명이 오게 된다.
실행결과
SELECT * FROM ITEM ;
DTYPE ID NAME PRICE
Movie 1 영화이름 10000
SELECT * FROM MOVIE ;
ACTOR DIRECTOR ID
엑터 디렉터 1
▣ JPA 조인전략 - SINGLE_TABLE(단일 테이블 전략)
| 하나의 테이블에서 DTYPE으로 구분합니다.
장점
- 테이블이 하나만 생성이 되어 조회시 조인이 없으며 조회 성능이 빠릅니다.
단점
- 자식 Entity가 매핑한 Column은 null을 허용해야 합니다.
- 단일 테이블에 모든것을 저장하기 때문에 테이블이 커질 수 있습니다.
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
실행결과
SELECT * FROM ITEM;
DTYPE ID NAME PRICE ARTIST AUTHOR ISBN ACTOR DIRECTOR
Movie 1 영화이름 10000 null null null 엑터 디렉터
▣ JPA 조인전략 - TABLE_PER_CLASS(구현 클래스마다 테이블 전략)
※ 쓰면 안되는 전략
| Item 테이블을 없애고 Item에 있는 속성을 각각의 테이블의 속성에 넣는다.
장점
- 서브 타입을 명확하게 구분해서 처리할 때 효과적
- not null 제약조건을 사용 가능
단점
- insert때는 문제가 없지만 만약 Item의 5번을 찾을 때 ALBUM, MOVIE, BOOK 테이블을 전부다 찾는다. (UNION)
- 자식테이블을 통합해서 쿼리하기 어려움.
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
@Id
@GeneratedValue
private Long id;
private String name;
private int price;
}
실행결과
Hibernate:
create table album (
id bigint not null,
name varchar(255),
price integer not null,
artist varchar(255),
primary key (id)
)
Hibernate:
create table book (
id bigint not null,
name varchar(255),
price integer not null,
author varchar(255),
isbn varchar(255),
primary key (id)
)
Hibernate:
create table movie (
id bigint not null,
name varchar(255),
price integer not null,
actor varchar(255),
director varchar(255),
primary key (id)
)
SELECT * FROM MOVIE ;
ID NAME PRICE ACTOR DIRECTOR
1 영화이름 10000 엑터 디렉터
SELECT * FROM ALBUM ;
ID NAME PRICE ARTIST
SELECT * FROM BOOK ;
ID NAME PRICE AUTHOR ISBN
'프로그래밍 언어 > Spring Framework' 카테고리의 다른 글
[인프런 김영한] JPA - 프록시 (0) | 2021.02.10 |
---|---|
[인프런 김영한] JPA - @MappedSuperclass (0) | 2021.02.09 |
[SpringMvc] Spring Interceptor 설정하기 (HandlerInterceptor) (0) | 2021.02.08 |
[인프런 김영한] JPA - 기본키 매핑 방법(@Id, @GeneratedValue) (0) | 2021.02.07 |
[인프런 김영한] JPA - 데이터베이스 스키마 자동생성 (0) | 2021.02.07 |