자바 ORM 표준 JPA 프로그래밍 - 고급 매핑

서은경·2022년 5월 9일
0

Java

목록 보기
10/19

상속관계 매핑

  • 관계형 데이터베이스는 상속 관계 X
  • 슈퍼타입 서브타입 관계라는 모델링 기법이 객체 상속과 유사
  • 객체의 상속과 구조와 DB의 슈퍼타입 서브타입 관계를 매핑
  • 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법

Super : Item (id, name, price)
Sub : Book, Album, Movie

조인전략 (각각 테이블로 변환)

기본 옵션은 Item 한 테이블에 모두 생성됨

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Item {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private int price;
}

DTYPE 생성 어노테이션

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public class Item {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private int price;

자식 객체에서 저장될 값 지정 가능

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

⭕️장점1. 테이블 정규화
⭕️장점2. 외래 키 참조 무결성 제약조건 활용가능
⭕️장점3. 저장공간 효율화

❌단점1. 조회 시 조인을 많이 사용, 성능 저하
❌단점2. 조회 쿼리가 복잡함
❌단점3. 데이터 저장시 INSERT SQL 2번 호출

단일 테이블 전략

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public class Item {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private int price;

단일 테이블 전략은 @DiscriminatorColumn 이 없어도 DTYPE이 생성되어 있음

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn
public abstract class Item {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private int price;

⭕️장점1. 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
⭕️장점2. 조회 쿼리가 단순함

❌단점1. 자식 엔티티가 매핑한 컬럼은 모두 null 허용
❌단점2. 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다.상 황에 따라서 조회 성능이 오히려 느려질 수 있다.
(변경 관점에서 안좋음, 새로운 타입이 추가가 될 때 많은걸 뜯어야함)

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

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn
public abstract class Item {

    @Id @GeneratedValue
    private Long id;
    private String name;
    private int price;

!!! 이 전략은 데이터베이스 설계자와 ORM 전문가 둘 다 추천하지 않음 !!!

⭕️장점1. 서브 타입을 명확하게 구분해서 처리할 때 효과적
⭕️장점2. not null 제약조건 사용 가능

❌단점1. 여러 자식 테이블을 함께 조회할 때 성능이 느림 (UNION 필요)
❌단점2. 자식 테이블을 통합해서 쿼리하기 어려움

@MappedSuperclass

  • 공통 매핑 정보가 필요할 때 사용
  • DB는 완전히 다른데 객체 입장에서 속성만 상속받아 사용하고 싶을 때(ex. 생성시간, 생성자, 수정시간, 수정자 컬럼의 경우 모든 테이블에 있다)
  • 상속관계 매핑 X
  • 엔티티 X, 테이블과 매핑 X (BaseEntity 라는 테이블 생성 안됨, 속성만 내려줌)
  • 부모 클래스를 상속받는 자식 클래스에 매핑 정보만 제공 (em.find(BaseEntity) 불가)
  • 직접 생성해서 사용할 일이 없으므로 추상 클래스 권장
  • 테이블과 관계 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할
  • 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통 으로 적용하는 정보를 모을 때 사용

참고: @Entity 클래스는 엔티티나 @MappedSuperclass로 지 정한 클래스만 상속 가능

@MappedSuperclass
public abstract class BaseEntity {

    @Column(name = "INSERT_MEMBER")
    private String createdBy;
    private LocalDateTime createdDate;
    private String lastModifiedBy;
    private LocalDateTime lastModifiedDate;

extends로 상속받아 속성만 사용

public class Member extends BaseEntity{

** 까먹지 않기 위해 정규화 정리 !!
제 1정규화 : 테이블 컬럼이 원자값 하나
제 2정규화 : 종속 함수 제거 (부분키는 어느 속성의 결정자일 수 없음)
제 3정규화 : 이행 함수 제거 (A->B, B->C, A->C 제거)
BCNF : 모든 결정자가 후보키 (제3 정규화를 진행한 테이블에 대해 모든 결정자가 후보키가 되도록 테이블을 분해)

0개의 댓글

관련 채용 정보