LostCatBox

Advenced-JPA1-CH03

Word count: 423Reading time: 2 min
2023/06/19 Share

상품 주문

order Entity에서

  • 객체는 자율적이여야한다.
  • 따라서 필요한 create, remove, 자신의 주요 행동 메서드는 자신이 직접가지고있는것이 자율적이다.(캡슐화)
  • 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package jpabook.jpashop.domain;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "orders")
@Getter
@Setter
public class Order {
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "delivery_id")
private Delivery delivery;

private LocalDateTime orderDate;

private OrderStatus status; // 주문 상태 ORDER , CANCEL

//연관관계 메서드
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
orderItem.setOrder(this);
orderItems.add(orderItem);
}
public void setDelivery(Delivery delivery) {
delivery.setOrder(this);
this.delivery = delivery;
}

// 생성메서드 -> 해당 객체와 관련된 생성은 해당 entity가 가짐. 자율화 캡슐화
public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems) {
Order order = new Order();
order.setMember(member);
order.setDelivery(delivery);
for (OrderItem orderItem : orderItems) {
order.addOrderItem(orderItem);
}
order.setStatus(OrderStatus.ORDER);
order.setOrderDate(LocalDateTime.now());

return order;
}

// 비즈니스 로직
/**
* 주문 취소
*/
public void cancel() {
if (delivery.getStatus() == DeliveryStatus.COMP) {
throw new IllegalStateException("이미 배송완료, 취소 불가");
}

this.setStatus(OrderStatus.CANCELED);
for (OrderItem orderItem: orderItems) {
orderItem.cancel();
}
}


//조회 로직
/**
* 전체 주문 가격 조회
*/
public int getTotalPrice() {
int totalPrice = orderItems.stream().mapToInt(OrderItem::getTotalPrice).sum();
return totalPrice;
}

}

order service

1
2
3
4
5
6
7
// 주문 저장 -> 실제로 위에 연관관계에있는 모든 data save됨. cascade.all 옵션때문에
// 어떨때 좋을까? order에서 delivery orderItem 모두 생명 주기가 같다. -> 다른곳에서 delivery를 가져다 쓰지않고 오직 order에서만 사용
// 마찬가지로 OrderItem이 참조되는곳은 오직 order 한군대다. 이때 cascade.all이 적절하다
Order order = Order.createOrder(member, delivery, orderItem);

orderRepository.save(order);
return order.getId();
1
2
3
// 다른곳에서 new Order() 형식으로 생성하지못하도록 막음
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order {
  • 도메인 모델 패턴
    • 참고: 주문 서비스의 주문과 주문 취소 메서드를 보면 비즈니스 로직 대부분이 엔티티에 있다. 서비스 계층은 단순히 엔티티에 필요한 요청을 위임하는 역할을 한다. 이처럼 엔티티가 비즈니스 로직을 가지고 객체 지향의 특성을 적극 활용하는 것을 도메인 모델 패턴(http://martinfowler.com/eaaCatalog/ domainModel.html)이라 한다. 반대로 엔티티에는 비즈니스 로직이 거의 없고 서비스 계층에서 대부분의 비즈니스 로직을 처리하는 것을 트랜잭션 스크립트 패턴(http://martinfowler.com/ eaaCatalog/transactionScript.html)이라 한다.

주문 검색 기능 개발

동적 쿼리.

  • 추천 X

    • String 으로 조합
    • Criteria
  • 무조건 QueryDSL

CATALOG
  1. 1. 상품 주문
    1. 1.1. order Entity에서
    2. 1.2. order service
    3. 1.3. 주문 검색 기능 개발
      1. 1.3.1. 동적 쿼리.