본문 바로가기
학습/DB

고급매핑 - 상속관계

코동이 2022. 7. 7.

*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