Free Lines Arrow
본문 바로가기
DataBase/JPA

[JPA] 고급 매핑1: 상속관계 맵핑

by skahn1215 2021. 8. 8.
728x90
반응형

상속관계 맵핑

상속관계 맵핑에 대해 알아본다.

JPA 로 구현을 해본다.

 

 

 

상속관계 맵핑이란?

  • 관계형 DB 는 상속관계 없다.
    관계형 DB는 슈퍼, 서브타입 관계라는 모델링 기법이 객체 상속과 유사

  • 객체의 상속과 구조와 DB의 슈퍼, 서브 타임 관계를 매핑하는것

 

 

 

상속관계 맵핑전략의 종류

  • 조인 전략
  • 단일테이블 전략
  • 클래스마다 테이블 전략

 

 

 

어노테이션

@Inheritance(strategy=InheritanceType.XXX)

  • XXX에 들어가는 속성들
  • JOINED: 조인 전략
  • SINGLE_TABLE: 단일 테이블 전략
  • TABLE_PER_CLASS: 구련 클래스 마다 테이블 전략

 

@DiscriminatorColumn(name="DTYPE")

  • Child 의 Entity 네임이 들어간다.
  • 아래 예제로 설명

 

@DiscriminatorValue

찾아보자.

 

 

 

 

전략

 

Join 전략

  • DB 에서 정규화된 조인방식으로 해결한다.
  • JPA 와 가장 유사한 모델이다.
  • 제일 선호하는 전략이다.

 

장점

  • 정규화가 되어 있다.
  • 외래키 참조 무결성 제약 조건활용 가능하다.
    - 다른테이블에서 외래키를 탐조하여 아이템을 찾을때 Item 테이블만 보면된다.
  • 저장공간이 효율적이다.

단점

  • 조회시 조인을 많이 사용한다.
    - 하지만 큰 성능저하는 아니기 때문에 큰단점은 아니다.
  • INSERT 쿼리가 2번 나가게 된다.
    - MOVIE 테이블에 객체를 저장할때 1번
    - 맵핑을 위해 ITEM에 저장할때 1번

 

구현

 

Item

@Entity
// JOIN 전략으로 간다.
@Inheritance(strategy = InheritanceType.JOINED)

//DTYPE 을 생성해 준다.
// 클래스 명이 들어간다.
// 예를 들어 Movie7의 엔티티면 Movie7이 타입으로 들어간다.
// name을 써서 컬럼명을 변경해줄수 있다.
@DiscriminatorColumn
public abstract class Item7 {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;
}

 

Movie

@Entity
public class Movie7 extends Item7 {
    private String director;
    private String actor;
}

 

Main

public class joinstartegyEx {
    public static void main(String[] args) {

        // persistence.xml 의 persistence-unit name="hello" 를 넘긴다.
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

        // 매니저를 꺼내온다.
        EntityManager em = emf.createEntityManager();

        // 트랜잭션 얻어오고 실행한다.
        // JPA 는 트랜잭션 안에서 수행되어야 한다.
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        // exception 처리를 위해 try catch 문을 반드시 사용해야된다.
        try {
            Movie7 movie = new Movie7();
            movie.setName("셜록");
            movie.setDirector("누구지?");
            movie.setActor("배네딕트컴버배치");
            movie.setPrice(10000);

            em.persist(movie);
            em.flush();
            em.clear();

            Movie7 findMovie = em.find(Movie7.class, movie.getId());
            System.out.println(findMovie.getActor());

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        } finally {
            em.close();
        }
        emf.close();
    }
}

 

 

 

결과

  • 테이블들이 각각 만들어 졌다.
  • Item 에는 기본적인 정보들이 있고
  • Item을 상속받은 객체에 대해 필요정보만 담고 있는 Table 들이 만들어 졌다.

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

    
    create table Movie7 (
       actor varchar(255),
        director varchar(255),
        id bigint not null,
        primary key (id)
    )

    
    create table Album7 (
       artist varchar(255),
        id bigint not null,
        primary key (id)
    )

    
    create table Book7 (
       author varchar(255),
        isbn varchar(255),
        id bigint not null,
        primary key (id)
    )

 

Item Insert 결과

 

 

 

 

 단일 테이블 전략

  • 테이블 하나에 다 들어 간다.
  • 자동으로 DTYPE이 생긴다.

 

 

장점

  • 조인이 필요없다.
  • 쿼리가 단순하다.

 

단점

  • 자식엔티티가 매핑한 컬럼은 모두 null 허용
  • 모든 것을 저장하므로 테이블이 커실수 있다.
    - 성능이 떨어 질수도 있다.

 

구현

@Entity
// JOIN 전략으로 간다.
@Inheritance(strategy = InheritanceType.JOINED)

//DTYPE 을 생성해 준다.
// 클래스 명이 들어간다.
// 예를 들어 Movie7의 엔티티면 Movie7이 타입으로 들어간다.
// name을 써서 컬럼명을 변경해줄수 있다.
@DiscriminatorColumn
public abstract class Item7 {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;
}

 

 

결과

테이블 하나만 만들어 졌다.

Hibernate: 
    
    create table Item7 (
       DTYPE varchar(31) not null,
        id bigint not null,
        name varchar(255),
        price integer not null,
        author varchar(255),
        isbn varchar(255),
        artist varchar(255),
        actor varchar(255),
        director varchar(255),
        primary key (id)
    )

 

Item Insert 결과

 

 

 

 개별의 테이블을 만드는 전략

  • item을제외하고 상속받은 class 에대해서 모든 테이블을 다 만든다.

 

 

단점

  • 조회 할경우 타입을  Item 타입으로 조회할 경우
  • 찾을때 모든 테이블을 다 뒤져버린다.
  • 망한다.
  • 쓰지말자

 

결과

Hibernate: 
    
    create table Album7 (
       id bigint not null,
        name varchar(255),
        price integer not null,
        artist varchar(255),
        primary key (id)
    )
Hibernate: 
    
    create table Book7 (
       id bigint not null,
        name varchar(255),
        price integer not null,
        author varchar(255),
        isbn varchar(255),
        primary key (id)
    )

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

 

 

 

 

 

참고: 

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 본 강의는 자바 백엔

www.inflearn.com

 

 

728x90
반응형

'DataBase > JPA' 카테고리의 다른 글

[JPA] 프록시  (0) 2021.08.11
[JPA] @MappedSuperclass  (0) 2021.08.09
[JPA] 다양한 연관관계 맵핑  (0) 2021.08.07
[JPA] 연관관계 매핑기초5: 예제  (0) 2021.08.04
[JPA] 연관관계 매핑기초4: 정리  (0) 2021.08.03

댓글