주인을 정할 때 유의해야할 것은 비즈니스 적으로 생각하지 말고 데이터의 흐름과 관리, 유지보수를 고려하여 정한다.
양방향 참조는 실무에서 잘 쓰지 않는다.
N:1 양방향 연관관계 설정 코드를 살펴보자
Order Entity
@Entity
@Table(name="orders")
@Getter @Setter
public class Order {
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
}
Member Entity
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
private String name;
@Embedded // 내장타입 명시
private Address address;
@OneToMany(mappedBy = "member") // 연관관계의 거울, member 필드에 의해 매핑 된다.
private List<Order> orders = new ArrayList<>();
}
3. 상속 관계
예제에서 Item은 Book + Movie + Album과 상속 관계
상속관계 전략 3가지
public enum InheritanceType {
/** A single table per class hierarchy. */
SINGLE_TABLE,
/** A table per concrete entity class. */
TABLE_PER_CLASS,
/**
* A strategy in which fields that are specific to a
* subclass are mapped to a separate table than the fields
* that are common to the parent class, and a join is
* performed to instantiate the subclass.
*/
JOINED
}
예제에서는 SINGLE_TABLE 설정을 사용
dtype 컬럼으로 구분한다.
부모 Entity를 추상클래스로 생성
상속관계 설정을 코드로 살펴보자
Item Entity
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "dtype") // 자식 객체 구분 기준 컬럼
@Getter @Setter
public abstract class Item {
@Id @GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
}
Book Entity
@Entity
@DiscriminatorValue("B") // Item의 dtype에 들어갈 album 객체의 타입 값
@Getter @Setter
public class Book extends Item{
private String author;
private String isbn;
}
4. 1:1 관계
외래키를 가진 쪽이 주인이 된다.
Order와 Delivery에서 Order가 주인
1:1 관계 설정을 코드로 살펴보자
Order Entity
@OneToOne // 1:1 관계
@JoinColumn(name = "delivery_id")
private Delivery delivery;
Delivery Entity
@Entity
@Getter @Setter
public class Delivery {
@Id
@GeneratedValue
private Long id;
@OneToOne(mappedBy = "delivery")
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING) // ORDINAL로 설정하면 값이 추가되거나 순서가 바뀌면 기존 값이 바뀌어 장애 발생
private DeliveryStatus ststus; // READY, COMP
}
5. N:N 관계
실무에서는 절대 사용하지 않는다.
테이블에서는 1:N, N:1 관계가 되도록 중간 테이블이 필요
예제의 Category와 Item 관계
N:N 관계 코드
Category Entity
@Entity
@Getter @Setter
public class Category {
@Id @GeneratedValue
@Column(name = "category_id")
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "category_id"),
inverseJoinColumns = @JoinColumn(name = "item_id")) // 다대다 관계에서는 중간 테이블 매핑 필요
private List<Item> items = new ArrayList<>();
}
Item Entity
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
6. 번외) 자신을 참조할 때
Categoty에서 계층구조를 만들어야 할 때
예) 가전 - 컴퓨터 - 키보드
코드
Category Entity
// 카테고리의 계층 구조 설정, 자신을 참조할 때
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();