-
주문 리포지토리, 서비스 개발JPA/JPA 활용 2023. 7. 11. 18:11
주문 도메인을 이용해서 repository와 service를 개발할 것이다.
OrderRepository class
@Repository @RequiredArgsConstructor 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) {} // 검색 기능은 나중에 작성 }
repository는 save와 findOne을 해주는 것 말고 특별한 기능을 하지 않는다.
검색 기능은 쿼리를 많이 작성해야하기 때문에 다른 기능들을 전부 테스트한 다음에 별도로 작성할 것이다.
OrderService class
주문 기능
@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) { // 엔티티 조회 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); return order.getId(); }
주문을 기능을 하는 Service 계층의 함수이다. 주문을 요청할 때 사용자, 아이템을 받아오고 수량을 입력한다. 따라서 memberId, itemId로 엔티티를 조회한다. 이후에 배송정보를 생성하는데 Address는 예제를 단순화하기 위해 주소를 입력하지 않고 사용자의 address가 들어가게 했다. 이후에 주문 상품과 주문을 생성하는 createOrderItem과 createOrder를 호출했다. 그리고 주문을 저장한다.
원래대로라면 delivery, orderitem도 각각 persist를 해줘야한다.
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL) //order에 의해서 mapping이 되었다는 뜻 private List<OrderItem> orderItems = new ArrayList<>(); @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "delivery_id") private Delivery delivery;
하지만 Order 엔티티에서 cascade를 넣어줬는데 이 기능때문에 Item이 persist될 때 delivery와 orderItem도 같이 persist된다. cascade를 언제 사용하는지가 애매한데, delivery와 orderItem처럼 오직 order를 위해 존재하는 상황일 대만 cascade를 사용하고 만약 다른데에서도 delivery를 참조해서 사용한다면 cascade를 사용하면 안된다.
주문취소 기능
/** * 주문취소 */ @Transactional public void cancelOrder(Long orderId) { // 주문 엔티티 조회 Order order = orderRepository.findOne(orderId); // 주문 취소 order.cancel(); // JPA는 데이터베이스에 업데이트 쿼리가 자동으로 날라감 }
주문을 취소하는 기능이다. 주문 엔티티를 조회하고 그 주문을 취소해주면 된다. 원래는 업데이트 쿼리를 작성한 다음 DB에 날려줘야하지만 JPA는 데이터베이스에 업데이트 쿼리가 자동으로 날라가기 때문에 별도로 쿼리를 작성해주지 않아도 된다.
주문 조회 기능
OrderSearch 클래스
@Getter @Setter public class OrderSearch { private String memberName; //회원 이름 private OrderStatus orderStatus; // 주문 상태[ORDER, CANCEL] }
findAll 기능
public List<Order> findAll(OrderSearch orderSearch) { return em.createQuery("select o from Order o join o.member m" + " where o. status = :status " + " and m.name like : name", Order.class) .setParameter("status", orderSearch.getOrderStatus()) .setParameter("name", orderSearch.getMemberName()) .setMaxResults(1000) // 최대 1000건 .getResultList(); }
findAll 이라는 메서드를 통해 주문을 전체 조회할 수 있는 기능을 만들었다.
이후에 검색을 통해서 특정 주문내역을 조회하는 기능도 만들었다.
public List<Order> findAllByString(OrderSearch orderSearch) { //language=JPAQL String jpql = "select o From Order o join o.member m"; boolean isFirstCondition = true; //주문 상태 검색 if (orderSearch.getOrderStatus() != null) { if (isFirstCondition) { jpql += " where"; isFirstCondition = false; } else { jpql += " and"; } jpql += " o.status = :status"; } //회원 이름 검색 if (StringUtils.hasText(orderSearch.getMemberName())) { if (isFirstCondition) { jpql += " where"; isFirstCondition = false; } else { jpql += " and"; } jpql += " m.name like :name"; } TypedQuery<Order> query = em.createQuery(jpql, Order.class) .setMaxResults(1000); //최대 1000건 if (orderSearch.getOrderStatus() != null) { query = query.setParameter("status", orderSearch.getOrderStatus()); } if (StringUtils.hasText(orderSearch.getMemberName())) { query = query.setParameter("name", orderSearch.getMemberName()); } return query.getResultList(); }
JPQL을 사용해서 동적 쿼리를 짜서 String을 통한 주문 내역을 조회하는 것이다.
'JPA > JPA 활용' 카테고리의 다른 글
웹 계층 개발 - 회원 등록, 목록 조회 (0) 2023.07.11 주문 기능 테스트 (0) 2023.07.11 주문 도메인 개발 - 주문 로직 추가 (0) 2023.07.11 상품 리포지토리, 서비스 개발 (0) 2023.07.11 상품 엔티티 개발(비즈니스 로직) (0) 2023.07.11