JPA 상속 관계 매핑(@Inheritance)

4238 단어 mysqlJPAJPA

Item 객체(슈퍼타입)

@Entity
@Inheritance(strategy) //InheritanceType.JOINED || InheritanceType.SINGLE_TABLE || InheritanceType.TABLE_PER_CLASS
@DiscriminatorColumn //자동으로 DTYPE Column 생성 & 값 적재; InheritanceType.JOINED 일때만 사용하면 됨; 그 외에는 생략 가능
@Table(name = "p_item")
public abstract class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
    private int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

Album 객체(서브 타입)

@Entity
public class Album extends Item{

    private String artist;

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }
}

Book 객체(서브 타입)

@Entity
public class Book extends Item{

    private String author;
    private String isbn;

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
}

Movie 객체(서브 타입)

@Entity
@DiscriminatorValue(value = "mov") //DTYPE에 적재될 값을 정할 수 있음; 기본은 객체 이름/클래스 명
public class Movie extends Item{

    private String director;
    private String actor;

    public String getDirector() {
        return director;
    }

    public void setDirector(String director) {
        this.director = director;
    }

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }

}

1. @Inheritnace(strategy = InheritanceType.JOINED), @Inheritnace(strategy = InheritanceType.SINGLE_TABLE), @Inheritnace(strategy = InheritanceType.TABLE_PER_CLASS):
각각 조인 전략, 단일 테이블 전략, 구현 클래스마다 테이블 전략
2.@DiscriminatorColumn:
DTYPE Column 생성. name ="" 으로 column 이름 바꿀 수 있음
3. @DiscriminatorValue(value = "mov"):
해당 애너태이션이 없으면 기본으로 객체 이름/클래스 명으로 튜플에 적재됨. 해당 애너테이션으로 적재될때 이름을 지정해줄 수 있음.

1. @Inheritance(strategy =

InheritanceType.JOINED)

장점:
1. 테이블 정규화
2. 외래 키 참조 무결성 제약조건 활용가능
3. 저장공간 효율화
단점:
1. 단순 조회시에도 조인(JOIN)을 많이 사용, 성능 저하
2. 조회 쿼리가 복잡함

  1. 데이터 저장시 INSERT SQL 2번 호출 -> But, 실무에서는 크게 신경 쓸 필요는 없다

가장 선호되는 방법으로, 테이블을 확장하기에 용이하다.

2. @Inheritance(strategy = InheritanceType.SINGLE_TABLE)


장점:
1. 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
2. 조회 쿼리가 단순함
단점:
1. 자식 엔티티가 매핑한 컬럼은 모두 NULL 허용
2. 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다. 상황에 따라서 조회 성능이 오히려 느려질 수 있다

  1. 투플에서 값이 NULL을 갖는 Column이 존재하게 됨

그러므로, 단일 테이블 전략은 테이블이 단순하거나, 확장 가능성이 적을때 사용하는 게 적합합니다.

3. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)


장점:
1. 서브 타입을 명확하게 구분해서 처리할 때 효과적
2. NOT NULL 제약조건 사용 가능
단점:
1. 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION 필요)

  1. 자식 테이블을 통합해서 쿼리하기 어려움

실무에서는 사용하지 않는 것이 좋다.
데이터베이스 설계자와 ORM 전문가 둘 다 선호하지 않는 방식이며, 상속 관계의 테이블들을 묶어 주지 않기 때문에 용이하지 않다.

좋은 웹페이지 즐겨찾기