-
[JPA] 객체간의 매핑기초/JPA 2022. 10. 11. 11:40
상속
DB에는 상속 개념이 없지만 DB모델링 기법중 슈퍼타입 - 서브타입 모델링 기법이 상속 개념과 비슷하다.
1. 조인전략
- 각각의 엔티티를 만든다.
- 자식 테이블은 부모 테이블의 기본 키를 받아서 기본 키 + 외래 키로 사용하는 전략
- 부모 테이블에서는 자식테이블을 구분하는 컬럼을 생성
Character ID
이름
능력치
Jobs (자식 구분 컬럼)Warrior Mage Rogue Character_ID (PK, FK)
힘(power)Character_ID (PK, FK)
지능(intellect)Character_ID (PK, FK)
행운(luck)<부모 클래스>
@Entity @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = "JOBS") public abastract class Charecter { .... }
<자식 클래스>
@Entity @DiscriminatorValue("A") //@PrimaryKeyJoinColumn(name = "WARRIOR_ID") public class Warrior extends Character { .... }
@Inheritance
- 상속 매핑시 부모클래스에 작성되는 어노테이션
- 매핑 전략 지정
@DiscriminatorColumn
- 부모 클래스에서 사용되는 구분 컬럼명
- JPA 표준명세에는 작성하라고 명시되어 있지만, 몇몇 구현체에서 생략가능
@DiscriminatorValue
- 자식 클래스에서 부모클래스의 구분 컬럼명에 저장될 값
@PrimaryKeyJoinColumn
- 자식 테이블의 기본 키 컬럼명을 변경할 때 사용되는 어노테이션
- 기본값은 부모 테이블의 ID 컬럼명
조인 전략의 장/단점
장점
- 정규화된 테이블과 외래키 참조 무결성 ( RDB의 장점 )
- 불필요한 저장공간을 없앨 수 있다.
단점
- 조인으로 인한 성능 저하
- 조회 쿼리의 복잡
- INSERT SQL이 2번 생성
2. 단일 테이블 전략
- 테이블을 하나만 사용한다.
- 구분 컬럼을 사용 해 자식 클래스를 구분한다.
- 조인을 사용하지 않아 일반적으로는 가장 빠르다.
- DiscriminatorColumn 을 꼭 설정 해야 한다.
- DiscriminatorValue를 지정하지 않으면 기본으로 엔티티 이름을 사용한다.
Character ID
이름
능력치
Jobs (자식 구분 컬럼)
힘(power)
지능(intellect)
행운(luck)<부모 클래스>
@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) // JOIN전략에서 SINGLE_TABLE 전략으로 변경 @DiscriminatorColumn(name = "JOBS") public abastract class Charecter { .... }
<자식 클래스> : 자식 클래스는 조인 전략과 동일하다.
@Entity @DiscriminatorValue("A") public class Warrior extends Character { .... }
단일 테이블의 장/단점
장점
- 조인이 필요 없어 쿼리가 단순하며 일반적으로는 조회 성능이 빠르다.
단점
- 다른 엔티티의 컬럼 값은 null이 들어 가므로 모두 null을 허용해야하며 불필요한 값이 들어가게 된다.
- 많은 타입이 존재하게 되는 경우 조회 성능이 떨어질 수 있다.
3. 구현 클래스 마다 테이블 전략
- 부모 테이블이 따로 존재하지 않고 각각의 테이블에 입력된다.
Warrior Mage Rogue ID
이름
능력치
Character_ID (PK, FK)
힘(power)ID
이름
능력치
Character_ID (PK, FK)
지능(intellect)ID
이름
능력치
Character_ID (PK, FK)
행운(luck)<부모 클래스>
@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) // 전략 변경 //구분 컬럼 삭제 public abastract class Charecter { .... }
<자식 클래스> : 자식 클래스도 구분 값을 삭제한다.
@Entity //구분 값 삭제 public class Warrior extends Character { .... }
구현 클래스마다 테이블 전략의 장/단점
장점
- 서브 타임을 구분해서 처리할 때 효과적이다.
- not null 제약조건 사용이 가능하다.
- 구분에 사용되는 어노테이션을 사용하지 않는다.
단점
- 여러 자식 테이블 함께 조회하기 어렵고 성능이 느리다( UNION )
*결론 : 추천하지 않는 전략이다.
Entity가 아닌 공통 로직 상속
@MappedSuperclass
- @Entity와 다르게 실제 테이블과는 매핑 되지않고 상속 목적으로만 사용한다.
- 생성날짜와 변경날짜에 대한 공통 컬럼
<부모 클래스>
@MappedSuperclass public abstract class BaseEntity { @CreatedDate @Column(name = "regDate", updatable = false) private LocalDateTime regDate; @LastModifiedDate @Column(name = "modDate", updatable = true) private LocalDateTime modDate; }
<자식 클래스>
@Entity // /** 매핑 정보 변경 시 사용하는 어노테이션 @AttributeOverride(name = "regDate", column = @Column(name = "REGIST_DATE")) @AttributeOverrides({ @AttributeOverride(name = "regDate", column = @Column(name = "REGIST_DATE")), @AttributeOverride(name = "modDate", column = @Column(name = "MODIFY_DATE")) }) /** public class Warrior extends BaseEntity { .... }
- 부모 클래스에는 Entity 어노테이션 대신 MappedSuperClass 어노테이션을 사용한다.
- 부모 클래스는 실제 테이블이 아니다.
- 자식 클래스는 부모클래스의 Column을 상속받는다.
- 매핑 정보를 변경하려면 AttributeOverride 어노테이션을 사용하여 변경한다.
'기초 > JPA' 카테고리의 다른 글
[JPA] 식별관계, 비식별 관계, 복합키 (0) 2022.10.11 [JPA] 연관관계 (0) 2022.10.08 [JPA] JPA 어노테이션 (0) 2022.10.08 [JPA] 영속성 컨텍스트 (2) 2022.10.08