JPA 활용1 - 주문 도메인 개발

기석·2022년 5월 30일
0
post-thumbnail

스프링 부트와 JPA 활용1 강의를 듣고 정리한 내용입니다.

구현 기능

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

주문 엔티티

연관관계 메서드

연관관계 메서드를 통해 관련된 내용들을 한 번에 처리 해주는 것이 외부에서 Setter에 접근하게 하는 것보 좋다.

//==연관관계 메서드==//
 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);
 }

생성 메서드

객체 생성시에 Setter를 통해 접근하는 것보다 생성 메서드를 제공하는 것이 좋다.
메서드와 생성자는 저번 시간에 이야기 했듯이 따로 나누어 제공하는 것이 좋다.

//==생성메서드==//
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) {
	 	orderItem.cancel();
	 }
 }
 //==조회 로직==//
 /** 전체 주문 가격 조회 */
 public int getTotalPrice() {
 	int totalPrice = 0;
 	for (OrderItem orderItem : orderItems) {
 		totalPrice += orderItem.getTotalPrice();
 	}
 	return totalPrice;
 }

주문 서비스

주문 서비스는 주문 엔티티와 주문 상품 엔티티의 비즈니스 로직을 이용해서 각 기능을 제공한다.

/** 주문 */
 @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());
	delivery.setStatus(DeliveryStatus.READY);
	//주문상품 생성
	OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count);
	//주문 생성
	Order order = Order.createOrder(member, delivery, orderItem);
	//주문 저장
	orderRepository.save(order);
	return order.getId();
 }
 /** 주문 취소 */
 @Transactional
 public void cancelOrder(Long orderId) {
	//주문 엔티티 조회
	Order order = orderRepository.findOne(orderId);
 	//주문 취소
 	order.cancel();
 }

개인적으로는 orderRepository.findOne -> em.find(Order.class, id)로 찾은 order 엔티티에서 cancel 메서드를 호출할 수 있는 것이 신기했다.


주문 검색 기능 - 동적 쿼리

  1. JPQL 문자열로 처리 - 코드가 말도 안되게 길고 복잡해짐 (sql문을 다 만들어야함)
  2. JPQL Criteria로 처리 - JPA 표준 스펙이고 문자열보단 낫지만 역시 복잡하다.
  3. Querydsl이 가장 멋진 해결책. 지금은 언급만 하고 넘어감
profile
블로그 이사갔어요 https://kiseoky.tistory.com

0개의 댓글