고급 매핑

동현·2021년 7월 26일

7장 고급 매핑

객체지향 언어를 사용해본 사람이라면 당연히 상속 관계에 대해 알고있을것이다.

그렇다면 관계형 데이터 베이스에는 상속 관계가 있을까?

이에 대한 답은 "없다" 이다. 그렇다면 어떻게 상속 관계를 DB에 표현 할 수 있을까?

💁 이는 슈퍼 타입, 서브 타입 관계와 가장 유사하다고 볼 수 있다.

  • 각각의 테이블로 변환 ( 조인전략 )
  • 통합 테이블로 변환 ( 단일 테이블 전략 )
  • 서브 타입 테이블로 변환 ( 테이블 전략 )

조인 전략 (Joined Strategy)

엔티티 각각을 모두 테이블로 만들고 부모 테이블의 키를 받아 기본키 + 외래키 ( 복합키로 ) 사용

→ 조회시 조인 전략 사용

‼️주의점

객체는 타입이 있지만 테이블은 타입이 없다. 따라서 따로 DTYPE 컬럼을 구분 컬럼으로 사용

@Inheritance(strategy = InheritanceType.JOINED) : 상속 매핑은 부모 클래스에 Inheritance를 사용해야 하며 조인 전략이기 때문에 JOINED를 선택

@DiscriminatorColumn(name = "DTYPE") : 부모 클래스에 구분 컬럼을 지정

장점

  • 테이블 정규화
  • 외래키 참조 무결성 제약 조건 활용 가능
  • 저장공간을 효율적으로 사용

단점

  • 조인이 많이 사용되므로 성능저하 초래될수 있음
  • 조회 쿼리 복잡
  • INSERT SQL 두번 실행

단일 테이블 전략

이름 그대로 테이블을 하나만 사용한다. (즉 하나에 다 때려박음)

조회 성능은 가장 뛰어남

‼️ 주의점

자식 엔티티가 매핑한 컬럼은 모두 Null 허용

장점

  • 조인이 필요 X 조회 성능 빠름
  • 조회 쿼리 단순

단점

  • 자식 엔티티가 매핑한 컬럼은 모두 null 허용
  • 단일 테이블에 모든것을 저장하기 때문에 테이블이 커질 가능성이 있다. (오히려 조회 성능이 떨어질수도 있음)

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

일반적으로 추천하지 않는다 (나는 객체지향적이지 못하다 생각함)

장점

  • 서브 타입 구분 처리시 효과적
  • Not null 제약조건 사용가능

단점

  • 여러 자식 테이블 조회시 성능이 느림
  • 자식 테이블 통합해서 쿼리 하기 힘들다

@MappedSuperclass

이전에는 부모 클래스, 자식클래스를 모두 데이터 베이스 테이블과 매핑 했지만 이 어노테이션을 사용한다면 그렇지 않다.

부모 클래스는 테이블에 매핑하지 않고 부모 클래스에게 상속을 받는 자식 클래스에게만 매핑을 제공하게 된다.

→ 추상 클래스와 비슷 (abstract)

위와 같이 객체 기준으로 중복되는 필드 값이 있는경우 이를 묶어 baseEntity를 작성하게 된다.

부모로 부터 물려받은 매핑 정보를 재정의 하고 싶다면 @AttributeOverride를 사용

연관관계를 재정의 하고 싶다면 @AssociationOverrides를 사용하면 된다.

‼️ 주의점

부모 클래스는 당연히 em.find가 불가능


식별 관계 vs 비식별 관계

외래키가 기본키에 포함되는지에 따라 식별/ 비식별로 나뉘게 된다.

외래키 + 기본키가 식별자 이다 ⇒ 식별

외래키 / 기본키 (기본키만 식별자 ) ⇒ 비식별

‼️ 식별자가 2개인 경우에는 동등성 비교시 equals와 hashcode를 따로 구현 해야함

profile
여긴 어디 나는 누구?

0개의 댓글