Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

상속관계 본문

인프런/[인프런] 자바ORM 표준 JPA 프로그래밍

상속관계

Seung__ 2021. 8. 11. 21:34

1. 상속관계 매핑


  • 객체는 상속관계가 있으나, 관계형 데이터베이스는 상속관계가 없음
  • 슈퍼타입 서브타입 관계라는 모델링 기법이 그나마 객체 상속과 유사
  • 상속관계 매핑 : 객체의 상속 구조와 DB의 슈퍼타입 서브타입 관계를 매핑.
  • 슈퍼타입 : 공통 부분만 가지고 있음
  • 서브타입 : 개별적으로 가지는 속성들.

 

2. 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법


  • 각각 테이블로 변환 -> 조인 전략
    • PK, FK로 조인함
    • ITEM TABLE만 보면 구분이 안되는데..어떻게 구분..?->DTYPE
  • 통합 테이블로 변환 -> 단일 테이블 전략
    • 논리 모델을 한 테이블로 합쳐버림.
    • 한 테이블에 있으면 어떻게 구분..? DTYPE
  • 서브타입 테이블로 변환 -> 구현 클래스마다 테이블 전략
    • 테이블을 각각 구현.

3. 조인 전략


  • @Inheritance(strategy = InheritanceType.JOINED)
    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    public class Item {
    
        @Id @GeneratedValue
        private Long id;
    
        private String name;
    
        private int price;
    
    }​
  • JOINED를 선택하면 JPA가 위의 테이블 구조대로 만들어줌.
Hibernate: 
    
    create table Album (
       artist varchar(255),
        id bigint not null,
        primary key (id)
    )

Hibernate: 
    
    create table Book (
       author varchar(255),
        isbn varchar(255),
        id bigint not null,
        primary key (id)
    )
    
Hibernate: 
    
    create table Movie (
       actor varchar(255),
        director varchar(255),
        id bigint not null,
        primary key (id)
    )

Hibernate: 
    
    create table Item (
       id bigint not null,
        name varchar(255),
        price integer not null,
        primary key (id)
    )

 

  • MOVIE 를 생성하고 DB에 저장해보자.
    Movie movie = new Movie();
    movie.setDirector("A");
    movie.setActor("BBBB");
    movie.setName("mmmm");
    movie.setPrice(10000);
    em.persist(movie);
    
    tx.commit();​
  • 조회하면 어떻게 가져오지?
    Movie movie = new Movie();
    movie.setDirector("A");
    movie.setActor("BBBB");
    movie.setName("mmmm");
    movie.setPrice(10000);
    em.persist(movie);
    
    em.flush();
    em.clear();
    
    Movie findMovie = em.find(Movie.class, movie.getId());
    System.out.println("findMovie = " + findMovie);
    
    tx.commit();​
  • movie를 가지고 올 때  Movie로부터 id를 가지고 Item에 inner join을 통해 movie를 가져옴.
    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_6_0_,
            movie0_.director as director2_6_0_ 
        from
            Movie movie0_ 
        inner join
            Item movie0_1_ 
                on movie0_.id=movie0_1_.id 
        where
            movie0_.id=?
  • DTYPE, @DiscriminatorColumn
    • 부모 클래스인 Item에 @DIscriminatorColumn을 적용해보자.
    • 있는게 좋아. 
    • DTYPE이란 이름을 변경도 가능
      @DiscriminatorColumn(name = "blabla")
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {
  • ? ITEM 테이블에 DTYPE이 생겼다.
    • 기본적으로 DTYPE에는 엔티티 이름이 들어간다.
Hibernate: 
    
    create table Item (
       DTYPE varchar(31) not null,
        id bigint not null,
        name varchar(255),
        price integer not null,
        primary key (id)
    )
  • DTYPE을 통해 들어온 ITEM데이터가 뭔지 구분할 수 있다.

  • 그러면 DTYPE에 들어가는 이름이 기본이 엔티티 이름인데.. 엔티티이름 말고 변경 가능?
  • 쌉가능
  • @DiscriminatorValue("blabla")
    @Entity
    @DiscriminatorValue("M")
    public class Movie extends Item{​

DTYPE에 들어가는 이름 변경됨.

 

 

 

4. 싱글 테이블 전략


  • 아 너무 복잡함 하나로 합쳐
  • JPA 기본 전략.
  • 다 때려박고 DTYPE을 꼭 생성해서 구분할 수 있도록 하자.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public class Item {
  • ITEM 테이블만 생성됨.
Hibernate: 
    
    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)
    )
  • MOVIE와 관련없는 데이터는 null

  • INSER SQL 한 번만 날라가고, JOIN도 없어서 성능상 좋음.
  • 어?????????????DB설계를 바꿨는데.. 코드 바꾼게 거의 없다.
  • 와!!!!!!!!!!!!!JPA 장점!!!

 

 

 

5. 구현 클래스마다 테이블 생성


  • TABLE_PER_CLASS

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn
public abstract class Item {
  • ITEM TABLE이 안생김.
  • 찾을때 단점이 있음.
  • 조회할 때 부모클래스로 조회할 경우에 union all로 세 TABLE 다뒤짐.. ㄷㄷㄷㄷ
  • 비효율 적임..

 

 

6. 각 전략 별 장단점


  • 조인전략
    • 장점
      - 테이블 정규화
      - 외래 키 참조 무결성 제약조건 활용 가능
      - 저장공간 효율화
    • 단점
      - 조회 시 조인을 많이 사용, 성능 저하
      - 조회 쿼리가 복잡함
      - 데이터 저장시 INSERT SQL 2회 호출 -->큰 단점은 아님 ㅋㅋ
  • 싱글 테이블 전략
    • 장점
      - 조인이 필요 없어서 일반적으로 조회 성능이 빠름
      - 조회 쿼리가 단순해
    • 단점
      - 자식 엔티티가 매핑한 컬럼은 모두 NULL 허용 ㄷㄷㄷㄷ
      - 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다.
       - 상황에 따라서 조회성능이 오히려 안좋아
  • 구현 클래스마다 테이블 생성 전략
    • 사용 멈춰! 쓰지마!
    • DB설계자, ORM전문가 둘다 추천안함 ㅋㅋㅋㅋㅋ
    • 장점
      - 서브 타입을 명확하게 구분해서 처리할 때 효과적
      -  not null 제약조건 사용 가능
    • 단점
      - 여러 자식 테이블을 함께 조회할 때 성능 느려짐(union sql)
      - 자식 테이블을 통합해서 쿼리하기 어려움.

 

 

7. 정리


기본적으로 조인 전략을 사용하자. 필요한 경우 싱글 테이블과 비교.

정~~~~~~~말 단순하면 싱글테이블 쓰자 ㅋㅋ

 

 

8. GitHub : 210811 상속관계 매핑

 


 

GitHub - bsh6463/JPA

Contribute to bsh6463/JPA development by creating an account on GitHub.

github.com

 

'인프런 > [인프런] 자바ORM 표준 JPA 프로그래밍' 카테고리의 다른 글

[예제] 상속관계 매핑  (0) 2021.08.11
@MappedSuperclass  (0) 2021.08.11
[예제] 다양한 연관관계 추가  (0) 2021.08.11
다대다[N:M]  (0) 2021.08.11
일대일[1:1]  (0) 2021.08.10
Comments