1. 종류
- 일대일(1:1) : @OneToOne
- 일대다(1:N) : @OneToMany
- 다대일(N:1) : @ManyToOne
- 다대다(N:M) : @ManyToMany
2. 방향
- 단방향
- A 엔티티만 B 엔티티를 참조하는 것.
- 즉, 한 쪽만 참조하는 것을 말함.
- 양방향
- A 엔티티와 B 엔티티가 서로를 참조하는 것.
- JPA 객체지향 중심 설계에서는 단방향, 양방향 존재
- 데이터베이스 중심 설계 테이블에서 관계는 항상
일대일 단방향 매핑
- 회원들은 각자 자신의 장바구니를 하나 갖고 있으며 장바구니 입장에서 봐도 자신과 매핑되는 한 명의 회원을 갖는 일대일 매핑 구조
- 장바구니 Entity는 현재 회원 Entity에 대한 정보를 알고 있음
- 회원 Entity에는 장바구니(Cart) Entity와 관련된 소스가 전혀 없다는 것을 확인 가능
- 즉, 장바구니 Entity가 일방적으로 회원 Entity를 참조하고 있는 일대일 단방향 매핑
일대일 단방향 매핑 예시
1. Cart (장바구니) Entity 생성
package kr.spring.cart.entity;
import jakarta.persistence.*;
import kr.spring.member.entity.Member;
import kr.spring.utils.entity.BaseEntity;
import lombok.*;
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "cart_id")
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;
}
2. CartRepository
- 장바구니 조회를 위한 Repository
import kr.spring.cart.entity.Cart;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CartRepository extends JpaRepository<Cart, Long> {
}
다대일 단방향 매핑
- 장바구니에는 고객이 관심이 있거나 나중에 사려는 상품들을 담아둠
- 하나의 장바구니에는 여러 개의 상품들이 들어갈 수 있음
- 하나의 상품은 여러 장바구니에 장바구니 상품으로 들어갈 수 있음
1. CartItem Entity 생성
import jakarta.persistence.*;
import kr.spring.item.entity.Item;
import kr.spring.utils.entity.BaseEntity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
public class CartItem extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "cart_item_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cart_id")
private Cart cart;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
private int count;
}
양방향 매핑
- 단방향 매핑이 2개 있는 구조 1:N ⇒ @OneToMany / N:1 ⇒ @ManyToOne
- 현재까지는 장바구니 상품 Entity가(CartItem) 장바구니를(Cart) 참조하는 단방향 매핑
- 장바구니 Entity에 장바구니 상품 Entity를 일대다 관계 매핑을 추가하여 양방향 매핑으로 변경 가능
- ORDERS와 ORDER_ITEM 테이블을 ORDER_ID를 외래키로 조인하면 주문에 속한 상품이 어떤 상품들이 있는지 알 수 있고, 주문 상품은 어떤 주문에 속하는지를 알 수 있음
- 즉, 테이블은 외래키 하나로 양방향 조회가 가능
→ 다대일과 일대다는 반대 관계
→ 주문 상품 엔티티 기준에서 다대일 매핑이었으므로 주문 엔티티 기준에서는 주문 상품 엔티티와 일대다 관계로 매핑
→ 양방향 매핑에서는 ‘연관 관계 주인’을 설정해야 한다는 점이 중요
N:1 - 1:N 관계에서 N이 주인이 됨.
→ 주로 FK를 갖는 쪽이 주인 TAG가 POST를 참조하므로 TAG 테이블이 부모 엔티티로 간주됨.
@JoinColumn
→ 양방향 연관관계에서 주인을 뜻함.
→ DB에 실제로 컬럼이 생김.
→ 조회 + 추가, 삭제, 수정이 가능함.
(mappedBy = )
→ 주인이 아님을 뜻함. 즉, mappedBy는 주인 엔티티의 필드명을 가리킴.
→ DB에 올라가는 컬럼이 없음.
→ 오직 조회만 가능함.
→ 외래키(order_id)가 order_item 테이블에 있으므로 연관 관계의 주인은 OrderItem 엔티티
→ Order 엔티티가 주인이 아니므로 “mappedBy” 속성으로 연관 관계의 주인을 설정
→ 속성의 값으로 “order”를 적어준 이유는 OrderItem에 있는 Order에 의해 관리된다는 의미로 해석
→ 연관 관계의 주인의 필드인 order를 mappedBy의 값으로 세팅
다대다 매핑
- 실무에서 사용하지 않는 매핑
- 관계형 데이터베이스는 정규화된 테이블 2개로 다대다를 표현할 수 없음
- 연결 테이블을 생성해서 다대다관계를 일대다, 다대일 관계로 풀어냄
- 객체는 테이블과 다르게 컬렉션을 사용해서 다대다 관계를 표현할 수 있음
- item을 리스트 형태로 가질 수 있으며, item 엔티티도 member를 리스트로 가질 수 있음
- 다대다 매핑을 사용하지 않는 이유
- 연결 테이블에 컬럼을 추가할 수 없음
- 추가 컬럼이 필요한 경우가 많은데 하지 못함
- 엔티티를 조회할 때 어떤 쿼리문이 실행될지 예측하지 못함
'Web & Android > Spring Data JPA' 카테고리의 다른 글
[Spring Data JPA] 즉시로딩, 지연로딩 (0) | 2023.10.15 |
---|---|
[Spring Data JPA] 영속성 전이, 고아객체 (0) | 2023.10.15 |
[Spring Data JPA] Querydsl (0) | 2023.10.15 |
[Spring Data JPA] @Query (0) | 2023.10.14 |
[Spring Data JPA] JPA (0) | 2023.10.14 |