반응형
본 내용은 온라인 강의 사이트 인프런의 김영한 님의 강의 내용이 포함되어 있습니다.
'자바 ORM 표준 JPA 프로그래밍 - 기본편'
상속관계 매핑
관계형 데이터베이스에서는 상속관계가 존재하지 않는다.
하지만 관계형 데이터베이스의 슈퍼타입과 서브타입 관계라는 모델링 기법이 객체 상속과 유사하다.
따라서 상속관계 매핑은 객체의 상속 구조와 데이터베이스의 슈퍼타입 서브타입 관계를 매핑하는 것을 말한다.
슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법
- 각각 테이블로 변환 → 조인 전략
- 통합 테이블로 변환 → 단일 테이블 전략
- 서브타입 테이블로 변환 → 구현 클래스마다 테이블 전략
JPA에서는 데이터베이스의 테이블을 위 세 가지 어떤 방법으로 구현하더라도 모두 매핑이 가능하다.
주요 어노테이션
- @Inheritance(strategy=InheritanceType.XXX)
- JOINED : 조인 전략
- SINGLE_TABLE : 단일 테이블 전략
- TABLE_PER_CLASS : 구현 클래스마다 테이블 전략
- @DiscriminatorColumn(name=”XXX”) : 구분 컬럼 지정
- 지정하지 않으면 DTYPE으로 사용한다.
- @DiscriminatorValue(”XXX”) : 자식들은 구분 컬럼에 어떻게 저장될지 지정
- 지정하지 않으면 엔티티 이름 그대로 사용한다.
Item
public abstract class Item {
private Long id;
private String name;
private int price;
// Getter
// ...
// Setter
// ...
}
Album
public class Album extends Item{
private String artist;
// Getter
// ...
// Setter
// ...
}
Movie
public class Movie extends Item {
private String director;
private String actor;
// Getter
// ...
// Setter
// ...
}
Book
public class Book extends Item {
private String author;
private String isbn;
// Getter
// ...
// Setter
// ...
}
조인 전략(Joined Strategy)
조인 전략은 모든 엔티티를 각각의 테이블로 만들고 자식 테이블이 부모 테이블의 기본 키를 받아서 기본키 + 외래 키로 사용하는 전략이다.
- Item, Album, Movie, Book 네 가지 엔티티가 있다고 가정한다.
- 부모인 Item의 기본키를 기본키 + 외래 키로 사용하여 조회가 필요할 때 조인을 사용한다.
- 객체는 타입으로 구분할 수 있지만 테이블은 타입이라는 개념이 없기 때문에 DTYPE과 같은 구분하는 컬럼을 추가해야 한다.
조인 전략 - 코드
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn
public abstract class Item {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int price;
//Getter
//...
//Setter
//...
}
- @Inheritance의 strategy 속성을 InheritanceType.JOINED로 지정하여 조인 전략을 사용할 수 있다.
- @DiscriminatorColumn을 지정하여 별도의 구분 컬럼을 추가한다. (기본값 “DTYPE”)
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
...
}
@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
private String director;
private String actor;
...
}
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
private String author;
private String isbn;
...
}
- @DiscriminatorValue를 사용하여 자식 테이블을 구분 컬럼에 어떻게 저장할지를 정할 수 있다.
조인 전략의 장단점과 특징
장점
- 테이블이 정규화된다.
- 외래 키 참조 무결성 제약조건을 활용할 수 있다.
- 저장공간을 효율적으로 사용한다.
단점
- 조회 시 조인을 많이 사용하기 때문에 성능 저하가 발생한다.
- 조회 쿼리가 복잡하다.
- 데이터 저장 시 INSERT SQL을 2번 호출한다.
특징
- JPA 표준 명세는 구분 컬럼을 사용하도록 하지만 하이버네이트를 포함한 몇몇 구현체는 구분 컬럼 없이도 동작한다.
- @PrimaryKeyJoinColumn, @DiscriminatorColumn, @DiscriminatorValue
단일 테이블 전략
논리 모델을 하나의 테이블로 사용하는 전략이다.
- 상속받는 클래스들을 모두 하나의 테이블에 저장하는 방법이다.
- 구분 컬럼(DTYPE)을 통해 어떤 자식 데이터가 저장되어 있는지 알 수 있다.
- @DiscriminatorColumn이 필수로 생성된다.
단일 테이블 전략 - 코드
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn
public abstract class Item {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int price;
//Getter
//...
//Setter
//...
}
- @Inheritance의 strategy 속성을 InheritanceType.SINGLE_TABLE로 지정하여 단일 테이블 전략을 사용할 수 있다.
- @DiscriminatorColumn을 지정하여 별도의 구분 컬럼을 추가한다. (기본값 “DTYPE”)
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
...
}
@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
private String director;
private String actor;
...
}
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
private String author;
private String isbn;
...
}
- @DiscriminatorValue를 사용하여 자식 테이블을 구분 컬럼에 어떻게 저장할지를 정할 수 있다.
단일 테이블 전략의 장단점과 특징
장점
- 조인이 필요 없어 조회 성능이 빠르다.
- 조회 쿼리가 단순한다.
단점
- 자식 엔티티가 매핑한 컬럼은 모두 null값을 허용한다.
- 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다.
- 따라서 상황에 따라 조회 성능이 오히려 느려지는 경우도 생긴다.
특징
- @DiscriminatorColumn 어노테이션이 필수적이다. (구분 컬럼)
구현 클래스마다 테이블 전략
구현 클래스마다 테이블 전략은 아이템 테이블을 아예 생성하지 않고 자식 테이블들이 값을 가지도록 하는 전략이다.
이 전략은 상속 개념이 무의미해지기 때문에 권장하지 않는 전략이다.
- ITEM 테이블이 생성되지 않는다.
- 각 자식 테이블들에 알맞은 데이터가 들어가게 된다.
구현 클래스마다 테이블 전략 - 코드
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int price;
//Getter
//...
//Setter
//...
}
- Item 테이블이 존재하지 않기 때문에 @DiscriminatorColumn 어노테이션의 의미가 사라진다.
@Entity
@DiscriminatorValue("A")
public class Album extends Item{
private String artist;
...
}
@Entity
@DiscriminatorValue("M")
public class Movie extends Item {
private String director;
private String actor;
...
}
@Entity
@DiscriminatorValue("B")
public class Book extends Item {
private String author;
private String isbn;
...
}
구현 클래스마다 테이블 전략의 장단점
장점
- 서브 타입을 명확하게 구분하여 처리할 때 효과적이다.
- not null 제약조건을 사용할 수 있다.
단점
- 부모 타입으로 조회할 수 없는 문제가 발생한다.
- 여러 자식 테이블을 함께 조회할 때 성능이 느리다.(UNION SQL 필요)
- 자식 테이블을 통합해서 쿼리 하기가 어렵다.
@MappedSuperclass
@MappedSuperclass 어노테이션은 부모 클래스는 테이블과 매핑하지 않고 자식 클래스에게 공통 매핑 정보가 필요할 때 사용한다.
- 상속관계 매핑이 아니다. 테이블과 매핑하는 것도 아니다.
- 또한, 엔티티가 아니기 때문에 테이블도 생성하지 않는다.
- 조회 및 검색 불가능
- 부모 클래스를 상속받는 자식 클래스에 매핑 정보만 제공하는 역할을 한다.
- 여러 엔티티에 공통된 정보를 추가할 때 유용
- 직접 생성해서 사용할 일이 없으므로 추상 클래스를 권장한다.
@MappedSuperclass - 코드
BaseEntity
@MappedSuperclass
public abstract class BaseEntity {
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
//Getter
//...
//Setter
//...
}
- 공통적으로 가져야 할 데이터들을 필드에 선언한다.
- @MappedSuperclass 어노테이션을 지정한다.
@Entity
public class Member extends BaseEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
...
}
@Entity
public class Team extends BaseEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "TEAM_ID")
private Long id;
private String name;
...
}
- 필요한 엔티티를 상속하는 것으로 공통된 필드를 가지게 할 수 있다.
@MappedSuperclass 정리
- 테이블과 관계없고 단순히 엔티티가 공통으로 사용하는 매핑 정보를 모으는 역할을 한다.
- 주로 등록일, 수정일, 등록자, 수정자와 같은 전체 엔티티에서 공통적으로 적용하는 정보를 모을 때 사용한다.
- @Entity 클래스는 엔티티나 @MappedSuperclass로 지정한 클래스만 상속이 가능하다.
반응형
'프레임워크(Framework) > JPA' 카테고리의 다른 글
[JPA] 영속성 전이(CASCADE)와 고아 객체 (0) | 2022.12.07 |
---|---|
[JPA] 프록시와 연관관계 관리(지연 로딩과 즉시 로딩) (0) | 2022.12.06 |
[JPA] 다양한 연관관계 매핑 - 엔티티 매핑(Entity Mapping) - 6 (0) | 2022.12.04 |
[JPA] 단방향 연관관계와 양방향 연관관계 - 엔티티 매핑(Entity Mapping) - 5 (0) | 2022.12.03 |
[JPA] 연관관계 매핑이란? - 엔티티 매핑(Entity Mapping) - 4 (0) | 2022.12.02 |