Chapter 7: 고급 매핑
1. 상속 관계 매핑
관계형 데이터베이스는
상속
이라는 개념이 없다대신에
Super-Type Sub-Type
관계라는 모델링 기법이 객체의 상속 개념과 가장 유사하다ORM에서 이야기하는 상속 관계 매핑은 객체의
상속 구조
와 데이터베이스의슈퍼타입 서브타입 관계
를매핑
하는 것이다
슈퍼타입 서브타입 논리 모델을 실제 물리 모델인 테이블로 구현하는 방법 3가지
각각의 테이블로 변환
각각을 모두 테이블로 만들고 조회할 때 조인을 사용
JPA에서는
조인 전략
이라 한다
통합 테이블로 변환
테이블을 하나만 사용해서 통합
JPA에서는
단일 테이블 전략
이라 한다
서브 타입 테이블로 변환
서브 타입마다 하나의 테이블을 만든다
JPA에서는
구현 클래스마다 테이블 전략
이라 한다
1-1. 조인 전략
엔티티 각각을 모두 테이블로 만들고, 자식 테이블이 부모 테이블의
기본 키
를 받아서기본 키 + 외래 키
로 사용하는 전략조회할 때 JOIN을 자주 사용!
주의할 점
객체는 타입으로 구분할 수 있지만, 테이블은 타입의 개념이 없다
따라서 타입을 구분하는 칼럼을 추가해야 한다!
장점
테이블이
정규화
된다외래 키 참조 무결성 제약조건을 활용할 수 있다
저장공간을 효율적으로 사용한다
단점
조회할 때 조인이 많이 사용되므로 성능이 저하될 수 있다
조회 쿼리가 복잡하다
데이터를 등록할 INSERT SQL을 두 번 실행한다
특징
하이버네이트를 포함한 몇몇 구현체는 구분 컬럼 없이도 동작한다
1-2. 단일 테이블 전략
이름 그대로 테이블을 하나만 사용하고,
구분 컬럼
으로 어떤 자식 데이터가 저장되었는지 구분조회할 때 조인을 사용하지 않으므로 일반적으로 가장 빠름!
주의할 점
자식 엔티티가 매핑한 컬럼은 모두
null을 허용
한다는 점
장점
조인이 필요 없으므로 일바넞긍로 조회 성능이 빠르다
조회 쿼리가 단순하다
단점
자식 엔티티가 매핑한 컬럼은 모두 null을 허용해야 한다
단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다
상황에 따라서는 조회 성능이 오히려 느려질 수 있따
특징
구분 컬럼을 꼭 사용해야 한다!
@DiscriminatorColumn
설정 필수!
@DiscriminatorColumn
을 지정하지 않으면 기본으로엔티티 이름
을 사용한다
1-3. 구현 클래스마다 테이블 전략
자식 엔티티마다 테이블을 만든다
자식 테이블에 각각 필요한 칼럼이 모두 있다
일반적으로 추천하지 않는 전략!
장점
서브 타입을 구분해서 처리할 때 효과적
not null 제약 조건 사용 가능
단점
여러 자식 테이블을 함께 조회할 때 성능이 느리다
SQL에 UNION을 사용해야 한다
자식 테이블을 통합해서 쿼리하기 어렵다
특징
구분 컬럼을 사용하지 않는다
2. @MappedSuperClass
@MappedSuperClass
부모 클래스는 테이블과 매핑하지 않고, 부모 클래스를 상속 받는 자식 클래스에게 매핑 정보만 제공하고 싶으면
@MappedSuperClass
를 사용하면 된다@MappedSuperClass
는 추상 클래스와 비슷한데,@Entity
는 실제 테이블과 매핑되지만@MappedSuperClass
는 실제 테이블과 매핑되지 않는다단순히 매핑 정보를 상속할 목적으로만 사용된다
테이블과는 관계가 없고, 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모아주는 역할을 한다
@MappedSuperClass
를 사용하면 등록 일자, 수정 일자, 등록자, 수정자와 같은 여러 엔티티에서 공통으로 사용하는 속성을 효괒거으로 관리할 수 있따
3. 복합 키와 식별 관계 매핑
3-1. 식별 관계 vs 비식별 관계
식별 관계
부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본 키 + 외래 키로 사용하는 관계
비식별 관계
부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계
필수적 비식별 관계
외래 키에 NULL을 허용하지 않음
연관관계를 필수적으로 맺어야 함
선택적 비식별 관계
외래 키에 NULL을 허용함
연관관계를 맺을지 말지 선택할 수 있음
3-2. 복합 키: 비식별 관계 매핑
JPA에서 식별자를 둘 이상 사용하려면, 별도의 식별자 클래스를 만들어야 한다
JPA는 복합 키를 지원하기 위해
@IdClass
와@EmbeddedId
2가지 방법을 제공한다@IdClass
식별자 클래스의 조건
식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 한다
Serializable
인터페이스를 구현해야 한다equals, hashcode를 구현해야 한다
기본 생성자가 있어야 한다
식별자 클래스는 public이어야 한다
@EmbeddedId
식별자 클래스에 기본키를 직접 매핑한다
식별자 클래스의 조건
@Embeddable
어노테이션을 붙여주어야 한다Serializable
인터페이스를 구현해야 한다equals, hashcode를 구현해야 한다
기본 생성자가 있어야 한다
식별자 클래스는 public이어야 한다
Last updated