김영한 님의 "자바 ORM 표준 JPA 프로그래밍" 책을 정리한 포스팅 입니다.
1. 상속 관계 매핑
- 데이터베이스의 슈퍼타입-서브타입 논리를 테이블로 구현
조인 전략
- 엔티티 각각을 테이블로 생성 + 자식 테이블의 기본키를 기본키+외래키로 사용 (부모 테이블의 기본키 받기)
- 테이블에 컬럼을 따로 추가해주기 (DTYPE: 구분 컬럼)
- 테이블 정규화 O + 참조 무결성 제약 O (외래키)
- 단점: 조회 쿼리 복잡 + 삽입 쿼리 두 번 실행
@Inheritance
- 조인 전략 지정 (상속 매핑 시)
- 부모 클래스에 작성
@DiscriminatorColumn
- 구분 컬럼 지정 (부모클래스)
- 자식 테이블 구분용
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item{
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
@DiscriminatorValue
- 구분 칼럼 값 (자식 클래스)
@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;
...
}
전략: 단일 테이블
- 테이블 하나만 사용 (모든 행 저장)
- (자식 엔티티) 모든 매핑 컬럼 -> nullable
- 조인 X (-> 빠름) / 테이블 크기 큼
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE")
public abstract class Item{
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
@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;
...
}
전략: 구현 클래스마다 테이블 생성
- 자식 엔티티마다 테이블 셍상
- not null 제약 조건 사용 가능
- 조인 O (여러 테이블 조회 시, 성능 느림)
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Item{
@Id @GeneratedValue
@Column(name = "ITEM_ID")
private Long id;
private String name;
private int price;
}
@Entity
public class Album extends Item{
private String artist;
...
}
@Entity
public class Movie extends Item{
private String director;
private String actor;
...
}
2. @MappedSuperclass
- 상속받는 자식 클래스에 매핑정보 제공 (부모클래스 테이블 생성 X)
@MappedSuperclass
- 부모클래스 지정 (상속할 매핑정보)
- 엔티티 X (추상클래스)
@MappedSuperclass
public abstract class BaseEntity {
@Id @GeneratedValue
private Long id;
private String name;
}
@AttributeOverride
- 연관관계 재정의 (부모로부터 상속)
@Entity
@AttributeOverride(name="id", column=@Column(name="MEMBER_ID")) // 부모에게 물려받은 매핑정보를 재정의하는 방법
public class Member extends BaseEntity {...}
@Entity
@AttributeOverrides({ // 둘 이상 재정의할 때 사용
name = "id", column = @Column(name = "SELLER_ID")),
name = "name", column = @Column(name = "SELLER_NAME"))
})
public class Seller extends BaseEntity {...}
3. 복합 키와 식별 관계 매핑
식별 관계 vs 비식별 관계
- 외래키가 기본키에 포함 여부
식별 관계
- 자식 테이블의 기본키를 기본키+외래키로 사용 (부모 테이블의 기본키 받기)
비식별 관계
- 자식 테이블의 외래키로 사용 (부모 테이블의 기본키 받기)
- 외래 키의 NULL 허용여부 (필수적 or 선택적)
- 필수적 비식별 관계 : 외래 키 NULL 허용 X
- 선택적 비식별 관계 : 외래 키 NULL 허용 O (연관관계를 맺을 지 선택 가능)
복합 키: 비식별 관계 매핑
@IdClass
- 복합 기본 키가 정의된 식별자 클래스를 설정합니다.
- 식별자 클래스의 속성명과 엔티티에서 사용하는 식별자의 속성명이 같아야 합니다.
@Entity
@IdClass(ParentId.class)
public class Parent {
@Id
@Column(name = "PARENT_ID1")
private String id1; //Parentld.id1과연결
@Id
@Column(name = "PARENT_ID2")
private String id2; //Parentld.id2와연결
}
public class ParentId implements Serializable {
private String id1; //Parent.id1 매핑
private String id2; //Parent.id2 매핑
public ParentId() { }
public ParentId(String id1, String id2) {
this.id1 = id1;
this.id2 = id2;
}
@Override
public boolean equals(Object o) {...}
@Override
public int hashCode() {. ..}
}
자식 클래스를 추가할 경우
- 부모 테이블의 기본 키 컬럼이 복합 키이므로 자식 테이블의 외래 키도 복합키 입니다.
- 외래 키 매핑 시 여러 컬럼을 매핑해야 하므로 @JoinColumns를 사용합니다.
@Entity
public class Child {
@Id
private String id;
@ManyToOne
@JoinColumns({
@JoinColumn(name = ”PARENT_ID1”, referencedColumnName = "PARENT_ID1"),
@JoinColumn(name = "PARENT_ID2", referencedColumnName = "PARENT_ID2")
})
private Parent parent;
}
@Embeddable
- 식별자 클래스를 정의합니다.
@Embeddable
public class ParentId implements Serializable {
@Column(name = "PARENT_ID1")
private String id1;
@Coluinn (name = "PARENT_ID2")
private String id2;
//equals and hashCode 구현
}
@EmbeddedId
- 매핑할 식별자 클래스를 지정합니다.
@Entity
public class Parent {
@EmbeddedId
private ParentId id;
private String name;
}
5. 엔티티 하나에 여러 테이블 매핑
@SecondaryTable
- 한 엔티티에 여러 테이블을 매핑할 수 있습니다.
name | 매핑할 다른 테이블의 이름 |
pkJoinColumns | 매핑할 다른 테이블의 기본 키 컬럼 속성 |
@Entity
@Table(name="BOARD")
@SecondaryTable(name = "BOARD_DETAIL",
pkJoinColumns=@PrimaryKeyJoinColumn(name="BOARD_DETAIL_ID"))
public class Board {
@Id @GeneratedValue
@Column(name="BOARD_ID")
private Long id;
private String title;
@Column(table = "BOARD_DETAIL")
private String content;
}
'Spring > Spring Data JPA' 카테고리의 다른 글
[Spring Data JPA] 3-7. Repository query keywords (0) | 2024.08.02 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] 8. 프록시와 연관관계 관리 (0) | 2023.12.28 |
[자바 ORM 표준 JPA 프로그래밍] 6. 다양한 연관관계 매핑 (0) | 2023.12.27 |
[자바 ORM 표준 JPA 프로그래밍] 5. 연관관계 매핑 기초 (0) | 2023.12.27 |
[자바 ORM 표준 JPA 프로그래밍] 4. 엔티티 매핑 (1) | 2023.11.28 |