주문 리포지토리 개발

학습 페이지

import jakarta.persistence.EntityManager;
import jpabook.jpashop.domain.Order;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Repository
@RequiredArgsConstructor //em을 자동생성하기 위한 생성자.
public class OrderRepository {

    private final EntityManager em;

    public void save(Order order){
        em.persist(order);
    }

    public Order findOne(Long id){
        return em.find(Order.class, id)
    }

    
    //==검색, 조회==//
//    public List<Order> findAll(OrderSearch orderSearch) {
//    }
}

마지막 로직은 검색기능에 쓰일 로직이다. 이 친구는 동적쿼리를 배워야 가능한 로직이라서 지금은 시그니처만 만들어놓고 나중에 다룰 것임.

주문서비스 개발

학습 페이지

주문 서비스가 가져야할 로직은 뭐가 있을까? 주문생성주문 취소가 가장 기본적인 로직일 것이다.

🔨 주문 생성

   //주문
    @Transactional
    public Long order(Long memberId, Long itemId, int count){ //주문하기 위해선 주문자id, 상품id, 수량이 필요하다.
        
    }

주문 메서드를 만들어보자. 인자에 memberId, ItemId, count가 필요하다. 이 녀석들을 어디선가 구해와야한다. 이 구해오는 역할을 누가 하는가? 바로 리포지들이다. 리포지들을 필드로 만들어주자..

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderService {

    private final OrderRepository orderRepository;
    private final MemberRepository memberRepository;
    private final ItemRepository itemRepository;

    //주문
    @Transactional
    public Long order(Long memberId, Long itemId, int count){ //주문하기 위해선 주문자id, 상품id, 수량이 필요하다.

    }

이를 바탕으로 주문 메서드를 만들면 다음처럼 된다.

package jpabook.jpashop.service;

import jpabook.jpashop.domain.Delivery;
import jpabook.jpashop.domain.Item.Item;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.domain.Order;
import jpabook.jpashop.domain.OrderItem;
import jpabook.jpashop.repository.ItemRepository;
import jpabook.jpashop.repository.MemberRepository;
import jpabook.jpashop.repository.OrderRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class OrderService {

    private final OrderRepository orderRepository;
    private final MemberRepository memberRepository;
    private final ItemRepository itemRepository;

    //주문
    @Transactional
    public Long order(Long memberId, Long itemId, int count){ //주문하기 위해선 주문자id, 상품id, 수량이 필요하다.

        //엔티티 조회
        Member member = memberRepository.findOne(memberId);
        Item item = itemRepository.findOne(itemId);

        //배송정보 생성
        Delivery delivery = new Delivery();
        delivery.setAddress(member.getAddress()); //예제를 단순하게 하기 위해 회원이 가진 배송지정보로 배송정보 생성

        //주문상품 생성
        OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count); //스태틱 팩토리 메서드 이용

        //주문 생성
        Order order = Order.createOrder(member, delivery, orderItem); //스태틱 팩토리 메서드 이용

        //주문 저장
        orderRepository.save(order); //orderItem과 delivery는 캐스케이딩 되어있음.
        return order.getId();
    }

    //취소

    //검색
}

보면.. 원래는 delivery도 리포지가 있어서 이 친구도 리포지에 save한 후에 order생성시에 인자로 넘겨줘야 하고, orderItem도 리포지가 따로 있어서 이 친구도 save한 후에 order생성시 인자로 넘겨줘야 한다고 한다.

그런데 지금 보면 order하나만 마지막에 save를 하고 있다. 왜? 그건 cascade옵션 덕분이다.