ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 상속관계 매핑
    JPA/JPA 기본 2023. 7. 11. 18:04

    상속관계 매핑이란 객체의 상속과 구조의 DB의 슈퍼타입 서브타입 관계를 매핑하는 것이다. 예를 들어, item의 카테고리가 Book, Movie, Album 3개의 엔티티가 있을 때 상속관계를 매핑하는 것이다.

    사진 : 김영한님 인프런 강의

    상속관계 매핑의 종류

    1. 조인 전략(JOINED)

    2. 단일 테이블 전략(SINGLE_TABLE)

    3. 구현 클래스마다 테이블 전략(TABLE_PER_CLASS)

     

    상속관계 매핑의 종류는 @Inheritance(strategy=InheritanceType.XXX) 로 구분된다. 

     

     

    1. 조인 전략(JOINED)

    사진 : 김영한님 인프런 강의

    Item 엔티티

    @Eintity
    @Getter @Setter
    @Inheritance(strategy = InheritanceType.JOINED)
    @DiscriminatorColumn(name = "dtype")
    public abstract class Item {
        @Id @GeneratedValue
        private Long id;
        
        private String name;
        private int price;
    }

    Item 엔티티는 추상 클래스로 만든다. 왜냐하면 다른 엔티티에서 Item 객체를 상속 받아서 사용할건데 추상 클래스로 만들지 않으면 Item 엔티티는 무조건 독단적으로 사용될 수 있다는 뜻이다.

     

     

    Album 엔티티

    @Entity
    @DiscriminatorValue("Album")
    @Getter @Setter
    public class Album extends Item {
         private String artist;
    }

     

     

    Movie 엔티티

    @Entity
    @DiscriminatorValue("Movie")
    @Getter @Setter
    public class Movie extends Item {
         private String director;
         private String actor;
    }

     

     

    Book 엔티티

    @Entity
    @DiscriminatorValue("Book")
    @Getter @Setter
    public class Book extends Item {
         private String author;
         private int isbn;
    }

     

     

    db에 데이터를 날리게되면 Book, Album, Movie 엔티티는 Item 객체를 상속받았기 때문에 같은 id를 갖는다.

    Movie movie = new Movie();
    movie.setDirector("aaaa");
    movie.setActor("bbbb");
    movie.setName("이름");
    movie.setPrice(10000);
    
    em.persist(movie);

    이렇게 db에다가 데이터를 날리면 Item 테이블에는 DTYPE : Movie, Id:1, Name : 이름, Price:10000이 저장되고 Movie 테이블에는 ACTOR :  bbbb, Director : aaa, Id : 1이라는 값이 저장되게 된다. 다음에 album을 저장하면 Id가 2로 시작된다.

    Book, Album, Movie에 데이터를 넣으면 Item 객체에 id가 1씩 증가하면서 저장되는 것이다.

     

    @DiscriminatorColumn(name = "dtype")을 Item 엔티티에 넣어서 dtype으로 분류할 수 있게 해주고 각각의 엔티티에 @DiscriminatorValue("Book")등을 넣어서 각각의 dtype을 설정해 주었다. 이렇게 해주는 이유는 Item 테이블만 조회해도 어느 엔티티에서 입력한 것인지 알수 있기 때문이다. 조인 전략에서는 선택이지만 다음에 나올 싱글 테이블 타입에서는 조인 전략이 필수이다.

     

     

    2. 단일 테이블 전략(SINGLE_TABLE)

    사진 : 김영한님 인프런 강의

    단일 테이블 전략은 쉽게 말해 한 테이블에 값을 다 넣어주고, DTYPE으로 구분하는 방식이다. 이전에 jpashop을 만들 때에도 이 전략을 사용했다.

     

    위의 코드에서 Item 엔티티만

    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)

    로 바꿔주면 된다.

     

    테이블을 보면

    DTYPE : Movie, ID : 1, Name : 이름, Price : 10000, Artist : Null, Author : Null, ISBN : Null, Actor : bbbb, Director : aaaa

    라고 테이블에 값이 저장된다.

     

    테이블에 모든 변수들이 다 들어있고, Book 엔티티의 변수들을 제외하면 다 Null 값으로 들어가게 된다.

     

     

    3. 구현 클래스마다 테이블 전략(TABLE_PER_CLASS)

    사진 : 김영한님 인프런 강의

    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

    타입을 TABLE_PER_CLASS로 바꿔주면 된다. 테이블을 만드는 create 쿼리를 살펴보면 Item 테이블은 만들지 않는 것을 확인할 수 있다.

     

     

     

    각각의 전략이 성능과 효율이 달라서 상황마다 사용해야 하는 것이 다를 수 있다. @Inheritance 애노테이션에서 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)의 SINGLE_TABLE을 바꿔주기만 해도 상속관계 매핑 종류를 바꿀 수 있는 것이 JPA의 장점이다.

     

     

     

    조인 전략의 장단점

    장점

    • 테이블 정규화
    • 외래 키 참조 무결성 제약조건 활용가능(다른 테이블에서 id를 조회할 때 Item_id만 확인하면 됨)
    • 저장공간의 효율화

    단점

    • 조회시 조인을 많이 사용, 성능 저하
    • 조회 쿼리가 복잡함
    • 데이터 저장시 INSERT 쿼리가 2번 나감

     

     

    단일 테이블 전략의 장단점

    장점

    • 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
    • 조회 쿼리가 단순함

    단점

    • 자식 엔티티가 매핑한 컬럼은 모두 Null을 허용
    • 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다. 상황에 따라서 조회 성능이 오히려 느려질 수 있다.

     

     

    구현 클래스마다 테이블 전략의 장단점

    장점

    • 서브 타입을 명확하게 구분해서 처리할 때 효과적
    • not null 제약조건 사용가능

    단점

    • 여러 자식 테이블을 함께 조회할 때 성능이 느림
    • 자식 테이블을 통합해서 쿼리하기 어려움

     

    마지막 전략인 구현 클래스마다 테이블 전략은 단점이 너무 크기때문에 절대 사용하지 않는 전략이다.

    'JPA > JPA 기본' 카테고리의 다른 글

    즉시로딩과 지연로딩  (0) 2023.07.11
    프록시  (0) 2023.07.11
    다양한 연관관계 매핑  (0) 2023.07.11
    연관관계 매핑 - 단방향, 양방향 연관관계  (0) 2023.07.11
    영속성 컨텍스트  (0) 2023.07.11
Designed by Tistory.