*JPA에서 상속관계 구현방식은?
1. 관계형 데이터베이스는 상속 관계가 없다.
2. "슈퍼타입 서브타입 관계"라는 모델링 기법이 "객체 상속"과 유사하다.
4. 상속관계 매핑 : 객체의 상속과 구조와 DB의 슈퍼타입 서브타입 관계를 매핑한다.
* 슈퍼타입 서브타입 논리 모델을 물리 모델로 구현하는 방법
1. 각각 테이블로 변환 (조인전략)
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@DiscriminatorColumn이 없어도 된다. 왜냐하면, id로 서로 조인하면 찾을 수 있기 때문이다. 안쓰면 DTYPE 없다.
@Entity
//@DiscriminatorValue("Album")
public class Album extends Item {
private String artist;
}
@Entity
//@DiscriminatorValue("Movie")
public class Movie extends Item {
private String director;
private String actor;
}
@Entity
//@DiscriminatorValue("Books")
public class Books extends Item {
private String author;
private String ISBN;
}
@Test
void ItemTest() {
Album album = new Album();
album.setName("앨범");
album.setPrice(5000);
album.setArtist("artist");
Album findAlbum = albumRepository.save(album);
System.out.println(">>>> findAlbum = " + findAlbum);
Movie movie = new Movie();
movie.setName("바람과함께사라지다");
movie.setPrice(10000);
movie.setActor("배우A");
movie.setDirector("감독B");
Movie findMovie = movieRepository.save(movie);
System.out.println(">>>> findMovie = " + findMovie);
List<Item> findItem = itemRepository.findAll();
System.out.println(">>>> findItem = " + findItem);
}
Hibernate:
insert
into
item
(name, price, dtype, id)
values
(?, ?, 'Album', ?)
Hibernate:
insert
into
album
(artist, id)
values
(?, ?)
>>>> findAlbum = Album(artist=artist)
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
item
(name, price, dtype, id)
values
(?, ?, 'Movie', ?)
Hibernate:
insert
into
movie
(actor, director, id)
values
(?, ?, ?)
Hibernate:
select
item0_.id as id2_4_,
item0_.name as name3_4_,
item0_.price as price4_4_,
item0_1_.artist as artist1_0_,
item0_2_.isbn as isbn1_3_,
item0_2_.author as author2_3_,
item0_3_.actor as actor1_5_,
item0_3_.director as director2_5_,
item0_.dtype as dtype1_4_
from
item item0_
left outer join
album item0_1_
on item0_.id=item0_1_.id
left outer join
books item0_2_
on item0_.id=item0_2_.id
left outer join
movie item0_3_
on item0_.id=item0_3_.id
2. 통합 테이블로 변환 (단일 테이블 전략)
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
//@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@DiscriminatorColumn이 필수다. 왜냐하면, 해당 칼럼으로 구분하지 않으면, 어느 자손의 엔티티인지 모른다.
필수이기 때문에 @DiscriminatorColumn을 적지 않아도 자동으로 생성해준다.
다른 테이블은 생기지 않는다.
@Test
void ItemTest() {
Album album = new Album();
album.setName("앨범");
album.setPrice(5000);
album.setArtist("artist");
Album findAlbum = albumRepository.save(album);
System.out.println(">>>> findAlbum = " + findAlbum);
Movie movie = new Movie();
movie.setName("바람과함께사라지다");
movie.setPrice(10000);
movie.setActor("배우A");
movie.setDirector("감독B");
Movie findMovie = movieRepository.save(movie);
System.out.println(">>>> findMovie = " + findMovie);
List<Item> findItem = itemRepository.findAll();
System.out.println(">>>> findItem = " + findItem);
}
Hibernate:
insert
into
item
(name, price, artist, dtype, id)
values
(?, ?, ?, 'Album', ?)
>>>> findAlbum = Album(artist=artist)
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
item
(name, price, actor, director, dtype, id)
values
(?, ?, ?, ?, 'Movie', ?)
3. 서브타입 테이블로 변환 (구현 클래스마다 테이블 전략)
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@DiscriminatorColumn이 필요없다. 왜냐하면 테이블이 서로 관련이 없기 때문에 구분할 필요가 없다. 써도 적용되지 않는다.
@Test
void ItemTest() {
Album album = new Album();
album.setName("앨범");
album.setPrice(5000);
album.setArtist("artist");
Album findAlbum = albumRepository.save(album);
System.out.println(">>>> findAlbum = " + findAlbum);
Movie movie = new Movie();
movie.setName("바람과함께사라지다");
movie.setPrice(10000);
movie.setActor("배우A");
movie.setDirector("감독B");
Movie findMovie = movieRepository.save(movie);
System.out.println(">>>> findMovie = " + findMovie);
List<Item> findItem = itemRepository.findAll();
System.out.println(">>>> findItem = " + findItem);
}
Hibernate:
insert
into
album
(name, price, artist, id)
values
(?, ?, ?, ?)
>>>> findAlbum = Album(artist=artist)
Hibernate:
call next value for hibernate_sequence
Hibernate:
insert
into
movie
(name, price, actor, director, id)
values
(?, ?, ?, ?, ?)
select
item0_.id as id1_4_0_,
item0_.name as name2_4_0_,
item0_.price as price3_4_0_,
item0_.artist as artist1_0_0_,
item0_.isbn as isbn1_3_0_,
item0_.author as author2_3_0_,
item0_.actor as actor1_5_0_,
item0_.director as director2_5_0_,
item0_.clazz_ as clazz_0_
from
( select
id,
name,
price,
artist,
null as isbn,
null as author,
null as actor,
null as director,
1 as clazz_
from
album
union
all select
id,
name,
price,
null as artist,
isbn,
author,
null as actor,
null as director,
2 as clazz_
from
books
union
all select
id,
name,
price,
null as artist,
null as isbn,
null as author,
actor,
director,
3 as clazz_
from
movie
) item0_
where
item0_.id=?
반응형
'학습 > DB' 카테고리의 다른 글
낙관적 잠금과 비관적 잠금으로 동시성 해결하기 (0) | 2022.08.19 |
---|---|
트랜잭션 격리 수준 (0) | 2022.08.12 |
JDBC란? (0) | 2022.07.05 |
HikariCP란? (0) | 2022.07.04 |
JPA를 이용해 페이징 만들기 (0) | 2021.12.15 |