twocowsong

실전 예제 본문

IT/JPA

실전 예제

WsCode 2022. 6. 7. 21:34

https://twocowsong.tistory.com/105

 

[실전 예제] 요구사항 분석과 기본 매핑

깃허브 정리 URL : https://github.com/sWineTake/jpa.git GitHub - sWineTake/jpa: 자바 ORM 표준 JPA 프로그래밍 - 김영한 자바 ORM 표준 JPA 프로그래밍 - 김영한. Contribute to sWineTake/jpa development..

twocowsong.tistory.com

앞의 실전 예제는 외래 키를 엔티티에 그대로 가져오는 문제가 있었습니다.

엔티티에서 외래 키로 사용한 필드는 제거하고 참조를 사용하도록 변경해보겠습니다.

 

객체 관계는 외래 키를 직접 사용하는것에서 참조를 사용하도록 변경하겠습니다.

@Setter
@Getter
@Entity
public class Member {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "MEMBER_ID")
   private String id;

   private String name;

   private String city;
   private String street;
   private String zipcode;

   @OneToMany(mappedBy = "member")
   private List<Order> orders = new ArrayList<>();
}
@Getter
@Setter
@Entity
@Table(name = "ORDERS")
public class Order {

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

   @ManyToOne
   @JoinColumn(name = "MEMBER_ID")
   private Member member; // 주문 회원

   @OneToMany(mappedBy = "order")
   private List<OrderItem> orderItems = new ArrayList<>();

   @Temporal(TemporalType.TIMESTAMP)
   private Date orderDate;

   @Enumerated(EnumType.STRING)
   private OrderStatus status;

   // 연관관계 메소드
   public void setMember(Member member) {
      if (this.member != null) {
         this.member.getOrders().remove(this);
      }
      this.member = member;
      member.getOrders().add(this);
   }

   public void addOrderItem(OrderItem orderItem) {
      this.orderItems.add(orderItem);
      orderItem.setOrder(this);
   }
}

public enum OrderStatus {
   ORDER, CANCEL
}

회원과 주문은 1 : N 관계입니다. 그반대인 주문과 회원은 N : 1 관계입니다.

Order -> Member로 참조하는 Order.member 필드와 Member -> Order로 참조하는 Member.orders 필드 중에 외래 키가 있는 Order.member가 연관관계의 주인입니다.

따라서 주인이 아닌 Member.orders에는 @OneToMany 속성에 mappedBy를 선언해서 연관관계의 주인인 member를 지정하였습니다. 참고로 여기서 지정한 member는 Order.member 필드입니다.

 

연관관계 편의 메소드

양방향 연관관계인 두 엔티티 간에 관계를 맺을 때는 원래 다음처럼 설정해야 합니다.

Member member = new Member();
Order order = new Order();

member.getOrders().add(order);
order.setMember(member);

 

여기서는 Order 엔티티에 setMember()라는 연관관계 편의 메소드를 추가했으므로 다음처럼 관계를 설정하면 됩니다.

Member member = new Member();
Order order = new Order();

order.setMember(member);
@Getter
@Setter
@Entity
@Table(name = "ORDER_ITEM")
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;
   
}

주문과 주문상품은 1 : N 관계고 그 반대는 N : 1 관계입니다.

OrderItem - Order로 참조하는 OrderItem.order 필드와 Order - OrderItem으로 참조하는 Order.orderItems 필드 중에 외래 키가 있는 OrderItem.order가 연관관계 주인입니다.

 

@Entity
@Getter
@Setter
public class Item {
   
   @Id
   @GeneratedValue
   @Column(name = "ITEM_ID")
   private Long id;
   
   private String name;
   private int price;
   private int stockQuantity;
   
}

비즈니스 요구사항을 분석해본 결과 주문상품에서 상품을 참조할 일을 많지만 상품에서 주문상품을 참조할 일은 거의 없습니다.

따라서 주문상품과 상품은 N : 1 단방향 관계로 설정하였습니다.

OrderItem - Item 방향으로 참조하는 OrderItem.Item필드만 사용해서 N : 1 단방향 관계로 설정했습니다.

 

주문한 회원을 객체 그래프로 탐색

String orderId = "주문 아이디";
Order order = em.find(Order.class, orderId);
// 주문한 회원, 참조 사용
Member member = order.getMember();

 

주문한 상품 하나를 객체 그래프로 탐색

String orderId = "주문 아이디";
Order order = em.find(Order.class, orderId);
OrderItem orderItem = order.getOrderItems().get(0);
Item item = orderItem.getItem();

'IT > JPA' 카테고리의 다른 글

연관관계의 주인(mappedBy)  (0) 2022.06.11
정리  (0) 2022.06.09
양방향 연관관계의 주의점  (0) 2022.06.06
양방향 연관관계 저장  (0) 2022.06.05
연관관계의 주인  (0) 2022.06.04