Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

주문 도메인 개발 본문

인프런/[인프런] Springboot와 JPA활용 1

주문 도메인 개발

Seung__ 2021. 8. 6. 12:43

1. 구현 기능


  • 상품 주문
  • 주문 내역 조회
  • 주문 취소

 

2. 순서


  • 주문 엔티티, 주문상품 엔티티 개발
  • 주문 repository 개발
  • 주문 service 개발
  • 주문 검색 기능 개발
  • 주문 기능 test

 

3. 주문 Entity


  • Order는 Member, Delivery, OrderItemd와 연관관계가 있음
  • OrderItem은 list로 가지고 있음.(OrderItem이 연관관계주인)
  • Order는 OrderItem을 읽어오기만 함.
  • Order가 생성될 때 Member, Delivery, OrdeItems 필요함.
  • 생성 메서드를 통해 한 번에 세팅하자.
    - 생성메서드가 가능한 이유는
    - Order가 컨트롤 하는 쪽이기 때문에 양방향으로 연관관계를 맺어주는 편의메서드가 있기 때문.
      //==생성메서드==//
        //order가 핵심임. 연관관계 편의 메서드가 order에 있어서 가능함.
        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;
        }​
  • OrderClass
    @Entity
    @Table(name="orders")
    @Getter
    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) //order_item의 어느 컬럼으로부터 orderItem 읽어옴?
        private List<OrderItem> orderItems = new ArrayList<>();
    
        @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(name = "delivery_id")
        private Delivery delivery;
    
        public void setOrderDate(LocalDateTime orderDate) {
            this.orderDate = orderDate;
        }
    
        private LocalDateTime orderDate; //주문 시간
    
        @Enumerated(EnumType.STRING)
        private OrderStatus status; //주문상태, enum
    
        public void setStatus(OrderStatus status) {
            this.status = status;
        }
    
        //양방향 연관관꼐 편의 메서드//
        //양방향 연관관계는 객체를 양방향으로 넣어줗어야함.
        //요렇게하면 실수도 줄이고 간단해짐.ㅋㅋ
        //어디에 있으면 좋아? 컨트롤 하는 쪽
        public void setMember(Member member){
            this.member = member;
            member.getOrders().add(this);
        }
    
        public void addOrderItem(OrderItem orderItem){
            orderItems.add(orderItem);
            orderItem.setOrder(this);
        }
    
        public void setDelivery(Delivery delivery){
            this.delivery = delivery;
            delivery.setOrder(this);
        }
    
    
        //==생성메서드==//
        //order가 핵심임. 연관관계 편의 메서드가 order에 있어서 가능함.
        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.CANCEL);
            for (OrderItem orderItem : orderItems) {
                //주문의 주문 아이템들에 대해서 CANCEL 처리
                orderItem.cancel();
            }
        }
    
        //==조회 로직==//
        /**
         * 전체 주문가격 조회
         */
        public int getTotalPrice(){
            int totalPrice = 0;
            for (OrderItem orderItem : orderItems) {
                totalPrice += orderItem.getTotalPrice();
            }
            return totalPrice;
        }
    }​

 

4. OrderItem class


  • 주문, 주문 취소에 따라 item의 stockQuantity가 변경되어야함.
  • 해당 아이템의 총 주문금액 반환
  • OrderItem와 Item은 단방향 다대일 연관관계. OrderItem이 Item을 참조함.
  • OrderItem생성시 Item, 주문가격, 수량 등이 필요함.
  • 생성메서드를 통해 처리.
@Entity
@Getter
@Setter
public class OrderItem {

    @Id
    @GeneratedValue
    @Column(name = "order_item_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "item_id") //Item의 PK를 FK로
    private Item item;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id")
    private Order order;


    private int orderPrice; //주문 금액
    private int count; //주문 수량

    //==생성 메서드==//
    public static OrderItem createOrderItem(Item item, int orderPrice, int count){
        OrderItem orderItem = new OrderItem();
        orderItem.setItem(item);
        orderItem.setOrderPrice(orderPrice);
        orderItem.setCount(count);

        item.removeStock(count);
        return orderItem;
    }


    //==비즈니스 로직==//

    /**
     * 주문수량 원복.
     */
    public void cancel() {
        getItem().addStock(count);
    }

    /**
     * 해당 item의 총 주문가격.
     */
    public int getTotalPrice() {
        return getOrderPrice() * getCount();
    }
}​

 

5. GitHub : 210806 Order Entity


 

GitHub - bsh6463/SpringBootJPA1

Contribute to bsh6463/SpringBootJPA1 development by creating an account on GitHub.

github.com

 

 

6. 생성메서드


- 생성메서드는 static으로 해야함.

- 왜냐? 외부에서 바로 생성매서드를 통해 객체 생성이 필요함.

- 클래스 레벨에서 바로 사용가능.

    //==생성메서드==//
    //order가 핵심임. 연관관계 편의 메서드가 order에 있어서 가능함.
    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;
    }

- 사용

        //주문 생성
        Order order = Order.createOrder(member, delivery, orderItem);

- 생성자가 아니라 별도의 생성 메서드를 사용하는 경우
- 기본 생성자를 통해 생성하지 못하도록 protected로 막아야 한다.

    /**
     * 기본 생성자 사용 안함.
     */
    protected Order() {
    }

 

- JPA에서 protected는 사용하지 말라는 의미.
 (JAVA : 동일 패키지내의 클래스,  해당 클래스를 상속받은 외부 패키지의 클래스만 접근 허용)

'인프런 > [인프런] Springboot와 JPA활용 1' 카테고리의 다른 글

주문 기능 테스트  (0) 2021.08.06
주문 repository, Service  (0) 2021.08.06
상품 domain, repository, service개발  (0) 2021.08.06
회원 기능 테스트  (0) 2021.08.06
MemberService 개발  (0) 2021.08.06
Comments