개집사의 개발새발

반응형

엔티티들은 대부분 다른 엔티티와 연관 관계를 맺고 있는데,

JPA에서는 엔티티에 연관 관계를 매핑해 두고 필요할 때 해당 엔티티와 연관된 엔티티를 사용하여 조금 더 객체지향적으로 프로그래밍할 수 있도록 도와줌

 

연관 관계 매핑의 종류

일대일 매핑의 예: 각 회원들의 장바구니

일대다 매핑의 예: 하나의 장바구니에 여러 개의 상품

 

일대일(1:1): @OneToOne

일대다(1:N): @OneToMany

다대일(N:1): @ManyToOne

다대다(N:M): @ManyToMany

 

* 다대일과 일대다는 반대 관계

 

엔티티 매핑시의 방향성

단방향

양방향

 

* 양방향 매핑에서는 '연관 관계 주인'을 설정해야 함

ㄴ 연관 관계의 주인은 외래키가 있는 곳으로 설정

ㄴ 연관 관계의 주인이 외래키를 관리(등록, 수정, 삭제)

ㄴ 주인이 아닌 쪽은 연관 관계 매핑 시 mappedBy 속성의 값으로 연관 관계의 주인을 설정

ㄴ 주인이 아닌 쪽은 읽기만 가능


일대일 단방향 매핑하기

회원 엔티티와 장바구니 엔티티 매핑 설정

import lombok.ToString;

import javax.persistence.*;

@Entity
@Table(name = "cart")
@Getter @Setter
@ToString
public class Cart {

    @Id
    @Column(name = "cart_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne   //일대일 매핑
    @JoinColumn(name="member_id")   //매핑할 외래키를 지정
    private Member member;
}

회원(Member) 엔티티에는 장바구니(Cart) 엔티티와 관련된 소스가 없음

장바구니 엔티티가 일방적으로 회원 엔티티를 참조

= 일대일 단방향 매핑

 


다대일 단방향 매핑하기

하나의 장바구니에는 여러 개의 상품들이 들어갈 수도 있고 같은 상품을 여러 개 주문할 수도 있으므로 몇 개를 담아줄 것인지도 설정이 필요

 

package com.shop.entity;

import lombok.Generated;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Getter @Setter
@Table(name="cart_item")
public class CartItem {

    @Id
    @Generated
    @Column(name = "cart_item_id")
    private Long id;

    @ManyToOne  // 다대일 관계로 매핑
    @JoinColumn(name="cart_id")
    private Cart cart;

    @ManyToOne
    @JoinColumn(name = "item_id")
    private Item item;  // 장바구니에 담을 상품의 정보

    private int count;  // 같은 상품을 장바구니에 몇 개 담을지 저장
}

 


다대일/일대다 양방향 매핑하기

장바구니 엔티티에 장바구니 상품 엔티티를 일대다 관계로 매핑을 해준다면 양방향 매핑이 됨

 

주문 - 주문 상품의 양방향 매핑

package com.shop.entity;

import com.shop.constant.OrderStatus;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "orders") //정렬할 때 사용하는 "order" 키워트가 있기 때문에 테이블로 orders를 지정
@Getter @Setter
public class Order {

    @Id @GeneratedValue
    @JoinColumn(name = "order_id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "member_id")
    private Member member; //한 명의 회원은 여러번 주문할 수 있음 -> 주문 엔티티 기준에서 다대일 단방향 매핑

    private LocalDateTime orderDate;    //주문일

    @Enumerated(EnumType.STRING)
    private OrderStatus orderStatus;    //주문 상태

    private LocalDateTime regTime;

    private LocalDateTime updateTime;
}

 


주문 상품 엔티티와 주문 엔티티의 단방향 매핑

package com.shop.entity;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Getter @Setter
public class OrderItem {
    
    @Id @GeneratedValue
    @Column(name = "order_item_id")
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "item_id")
    private Item item;  //하나의 상품은 여러 주문 상품으로 들어갈 수 있으므로 주문 상품 기준 다대일 단방향 매핑
    
    @ManyToOne
    @JoinColumn(name = "order_id")
    private Order order; // 한번의 주문에 여러 개의 상품을 주문할 수 있으므로 주문 상품 엔티티와 주문 엔티티를 다대일 단방향 매핑을 먼저 설정
    
    private int orderPrice; //주문가격
    
    private int count;  //수량
    
    private LocalDateTime regTime;
    
    private LocalDateTime updateTime;
}

다대다 매핑을 사용하지 않는 이유

연결 테이블에는 컬럼을 추가할 수 없기 때문

조인 컬럼뿐 아니라 추가 컬럼들이 필요한 경우가 많고, 엔티티를 조회할 때 member 엔티티에서 item을 조회하면 중간 테이블이 있기 때문에 어떤 쿼리문이 실행될지 예측하기도 쉽지 않음

연결 테이블용 엔티티를 하나 생성한 후 일대다 다대일 관계로 매핑하면 됨

반응형
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band