연관관계 매핑 실습 (+상속)

김강현·2023년 3월 24일
0

ORM-JPA

목록 보기
5/9

연관관계 설계

DB

아래는 다대다 관계인 Category 와 Item 의 외래키들을 저장할 중간 테이블이 추가되었다.
(다대다는 가급적 비추!! 예시니깐 사용해 보는 것! feat.김영한 개발자님)

Entity


Category 가 List<Item> 을 가지고, Item 은 List<Categories> 를 가지는 것을 볼 수 있음.

이런식으로 하면 되는데, 코드는 생략하겠음.

상속관계 매핑

객체의 상속관계와 비슷한 모델링 기법이 있음.
슈퍼타입 서브타입
상속관계 매핑 : 객체의 상속 구조와 DB의 슈퍼타입 서프타입 관계를 매핑

조인 전략


(덧) DiscriminatroColumn 어노테이션이 있어야, DTYPE 생김
-> DiscrimatorValue로 값 지정 가능!

Item.java

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {
    @Id @GeneratedValue
    private Long id;

    private String name;
    private int price;
}

Album.java

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

Book.java

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

Movie.java

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


위 그림 처럼 3개의 테이블 + Item 의 테이블 (DTYPE이 있는) 이 생성된다!

단일 테이블 전략

Item.java 의 annotation 만 바꾸어주면 된다

@Entity
// @Inheritance(strategy = InheritanceType.JOINED)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn

(덧) DiscriminatroColumn 어노테이션이 없어도 DTYPE 생김

위 그림처럼 하나의 테이블에 모든 변수들이 Column 으로 담겨 있는 것을 알 수 있다.

엄청나지 않은가? 어노테이션 하나 바꾸면, 상속 관련 테이블 전략이 한방에 바뀜...

구현 클래스마다 테이블 전략

@Entity
// @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
//@DiscriminatorColumn

(덧) 여기서 Item 이 abstract class 가 아니면, Item table은 만들어짐.

각 장단점!

조인

<장점>
데이터가 정규화 되어 있음
외래키 참조 무결성 제약조건 활용가능
저장공간 효율화

<단점>
조회시 조인 많이 사용
조회 쿼리 복잡
데이터 저장시 insert sql 2번 호출

단일 테이블 전략

<장점>
조회 성능이 빠름
조회 쿼리가 단순

<단점>
자식 엔티티가 매핑한 컬럼은 모두 null을 허용해줘야함
테이블이 커질 수 있고, 조회 성능이 오히려 느려질 수 있음

구현 클래스마다 테이블 전략

-> 왠만하면 쓰지 마라.
데이터베이스 설계자들 도 싫어하고, ORM 전문가들도 싫어하는!! 방식

조인 이나 단일테이블 중에 골라서 하면 된다!!

@MappedSuperclass

공통적으로 자주 쓰이는 것들. 엔티티 마다 필요한 값들 (ex. 생성시간, 수정 시간 등)
추상클래스로 사용하는 것을 추천!!

@MappedSuperclass
public abstract class BaseEntity {
    private String createdBy;
    private LocalDateTime createdDate;
    private String lastModifiedBy;
    private LocalDateTime lastModifiedDate;
}
  • 테이블과 관계 없고, 단순히 엔티티가 공통으로 사용하는 매핑정보를 모으는 역할
  • @Entity or @MappedSuperclass 이렇게 두개만 extends 가 가능함!!

예제

기존 사안에 추가로,

  • 상품의 종류는 음반, 도서, 영화가 있고 이후 더 확장될 수 있다.
  • 모든 데이터는 등록일과 수정일이 필수다.
  1. Item 이 Album, Book, Movie 의 super class가 되기 (DB는 single table로 ㄱㄱ)
  2. @MappedSuperclass 활용

profile
this too shall pass

0개의 댓글