[실습] Spring Data JPA를 이용한 데이터 액세스 실습
커피 주문 서비스 개발
1. 연관 관계 매핑 구현 실습
Order 클래스(주문)와 Coffee 클래스(커피)의 연관 관계 매핑 구현
- 구현 내용
- 주문과 커피는 다대다의 관계입니다.
- 다대다인 두 클래스의 연관 관계를 매핑하세요.
- 제한 사항
- @ManyToMany 애너테이션을 사용하면 안 됩니다.
- @OneToMany 애너테이션만 사용해서는 안 됩니다.
- @ManyToOne 애너테이션을 먼저 사용하고, 필요하다면 @OneToMany 애너테이션을 사용하면 됩니다.
- 회원이 주문한 주문 정보를 통해 주문_커피 정보를 조회할 수 있어야 합니다.
Member 클래스(회원)와 Stamp 클래스(도장)의 연관 관계 매핑 구현
- 구현 내용
- 회원과 스탬프는 일대일의 관계입니다.
- 스탬프는 회원이 주문하는 커피 한잔 당 찍히는 도장입니다.
- 소규모의 카페에서 주문한 커피 개수에 따라서 스탬프를 찍어주고 일정 스탬프 개수가 모이면 커피 가격을 할인해 주거나 무료 커피를 한 잔씩 제공하는 혜택을 떠올려보면 되겠습니다.
- Stamp 클래스의 필드 정보
- stampId(식별자)
- 데이터 타입: long
- 설명
- 테이블 상에서 자동 증가하는 기본키에 해당됩니다.
- stampCount(스탬프 개수)
- 데이터 타입: int
- 설명
- 주문하는 커피 한잔 당 stampCount가 1씩 증가합니다.
- createdAt(stamp 생성일)
- modifiedAt(stamp 수정일)
- stampCount 값이 업데이트될 때마다 함께 업데이트됩니다.
- stampId(식별자)
- 제한 사항
- 단방향 연관 관계 매핑으로 구현하고, 필요하다면 양방향 매핑을 구현합니다.
- 회원 정보를 통해 회원의 stampCount를 조회할 수 있어야 합니다.
2. 주문 기능 추가 구현
OrderService 클래스와 OrderController 기능 완성을 위한 추가 구현
Order 클래스와 Coffee 클래스, Member 클래스와 Stamp 클래스의 연관 관계 매핑이 끝났다면 회원이 주문한 커피 정보가 포함된 Response Body를 클라이언트가 전달받을 수 있도록 아래의 기능을 완성하세요.
- 구현할 내용
- 커피 주문 기능
- OrderService 클래스의 createOrder() 메서드에서 주문한 커피가 테이블에 존재하는 커피인지 체크하는 기능이 포함되어야 합니다.
- 주문한 커피의 수량만큼 회원의 스탬프 숫자를 증가시켜야 합니다.
- 예) 현재 회원의 스탬프 개수가 3이고, 주문한 총 커피 수량이 3이라면 주문 이후, 스탬프 개수는 3 + 3 = 6으로 업데이트되어야 합니다.
- 특정 주문 조회 기능
- OrderController 클래스의 getOrder() 핸들러 메서드에서 주문한 커피 정보가 ResponseEntity에 포함되어야 합니다.
- 주문 목록 조회 기능
- OrderController 클래스의 getOrders() 핸들러 메서드에서 주문한 커피 정보 목록이 ResponseEntity에 포함되어야 합니다.
- 커피 주문 기능
- ✅힌트
- 엔티티 간에 연관 관계를 매핑하는 @OneToMany, @ManyToOne 애너테이션에는 ‘cascade’라는 애트리뷰트가 있습니다. 이 속성의 값을 잘 설정하면 한 번의 save() 메서드 호출로 연관된 엔티티를 모두 저장 또는 업데이트할 수 있습니다.
- 주문한 커피 정보(OrderCoffee)를 ResponseEntity에 포함시키기 위해서는 OrderMapper에서 OrderCoffee와 OrderCoffeeResponseDto에 대한 추가 매핑이 필요하며, 매핑이 완료된 OrderCoffeeResponseDto 가 OrderReponseDto에 포함되어야 합니다.
클라이언트 쪽의 Response Body는 아래의 [그림 h-1], [그림 h-2]와 같은 형태여야 합니다.
- getOrder() 호출 시
[그림 h-1] getOrder() 호출 시, Request Body / Response Body 예
getOrders() 호출 시
[그림 h-2] getOrders() 호출 시, Request Body / Response Body 예
Coffee entity
package com.springboot.coffee.entity;
import com.springboot.order.entity.OrderCoffee;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Coffee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long coffeeId;
@Column(length = 100, nullable = false)
private String korName;
@Column(length = 100, nullable = false)
private String engName;
@Column(nullable = false)
private int price;
@Column(length = 3, nullable = false, unique = true)
private String coffeeCode;
// 커피 상태 추가
@Enumerated(value = EnumType.STRING)
@Column(length = 20, nullable = false)
private CoffeeStatus coffeeStatus = CoffeeStatus.COFFEE_FOR_SALE;
@Column(nullable = false)
private LocalDateTime createdAt = LocalDateTime.now();
@Column(nullable = false, name = "LAST_MODIFIED_AT")
private LocalDateTime modifiedAt = LocalDateTime.now();
@OneToMany(mappedBy = "order", cascade = CascadeType.PERSIST)
private List<OrderCoffee> orderCoffees = new ArrayList<>();
public void setOrderCoffee(OrderCoffee orderCoffee) {
this.orderCoffees.add(orderCoffee);
if (orderCoffee.getCoffee() != this) {
orderCoffee.setCoffee(this);
}
}
// 커피 상태 추가
public enum CoffeeStatus {
COFFEE_FOR_SALE("판매중"),
COFFEE_SOLD_OUT("판매중지");
@Getter
private String status;
CoffeeStatus(String status) {
this.status = status;
}
}
}
Member entity
package com.springboot.member.entity;
import com.springboot.order.entity.Order;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberId;
@Column(nullable = false, updatable = false, unique = true)
private String email;
@Column(length = 100, nullable = false)
private String name;
@Column(length = 13, nullable = false, unique = true)
private String phone;
@Enumerated(value = EnumType.STRING)
@Column(length = 20, nullable = false)
private MemberStatus memberStatus = MemberStatus.MEMBER_ACTIVE;
@Column(nullable = false)
private LocalDateTime createdAt = LocalDateTime.now();
@Column(nullable = false, name = "LAST_MODIFIED_AT")
private LocalDateTime modifiedAt = LocalDateTime.now();
@OneToMany(mappedBy = "member")
private List<Order> orders = new ArrayList<>();
@OneToOne(mappedBy = "member", cascade = CascadeType.ALL)
private Stamp stamp;
public void setStamp(Stamp stamp) {
this.stamp = stamp;
if (stamp.getMember() != this) {
stamp.setMember(this);
}
}
public Member(String email) {
this.email = email;
}
public Member(String email, String name, String phone) {
this.email = email;
this.name = name;
this.phone = phone;
}
public void setOrder(Order order) {
orders.add(order);
if (order.getMember() != this) {
order.setMember(this);
}
}
public enum MemberStatus {
MEMBER_ACTIVE("활동중"),
MEMBER_SLEEP("휴면 상태"),
MEMBER_QUIT("탈퇴 상태");
@Getter
private String status;
MemberStatus(String status) {
this.status = status;
}
}
}
Stamp entity
package com.springboot.member.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
@Getter
@Setter
@Entity
@NoArgsConstructor
public class Stamp {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long stampId;
@Column(nullable = false)
private int stampCount;
@Column(nullable = false)
private LocalDateTime createdAt = LocalDateTime.now();
@Column(nullable = false, name = "LAST_MODIFIED_AT")
private LocalDateTime modifiedAt = LocalDateTime.now();
@OneToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
public void setMember(Member member) {
this.member = member;
if (member.getStamp() != this) {
member.setStamp(this);
}
}
}
MemberService
package com.springboot.member.service;
import com.springboot.exception.BusinessLogicException;
import com.springboot.exception.ExceptionCode;
import com.springboot.member.entity.Member;
import com.springboot.member.entity.Stamp;
import com.springboot.member.repository.MemberRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Optional;
/**
* - 메서드 구현
* - DI 적용
* - Spring Data JPA 적용
*/
@Service
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public Member createMember(Member member) {
// 이미 등록된 이메일인지 확인
member.setStamp(new Stamp());
verifyExistsEmail(member.getEmail());
return memberRepository.save(member);
}
public Member updateMember(Member member) {
Member findMember = findVerifiedMember(member.getMemberId());
Optional.ofNullable(member.getName())
.ifPresent(name -> findMember.setName(name));
Optional.ofNullable(member.getPhone())
.ifPresent(phone -> findMember.setPhone(phone));
// 추가된 부분
Optional.ofNullable(member.getMemberStatus())
.ifPresent(memberStatus -> findMember.setMemberStatus(memberStatus));
findMember.setModifiedAt(LocalDateTime.now());
return memberRepository.save(findMember);
}
public Member findMember(long memberId) {
return findVerifiedMember(memberId);
}
public Page<Member> findMembers(int page, int size) {
return memberRepository.findAll(PageRequest.of(page, size,
Sort.by("memberId").descending()));
}
public void deleteMember(long memberId) {
Member findMember = findVerifiedMember(memberId);
memberRepository.delete(findMember);
}
public Member findVerifiedMember(long memberId) {
Optional<Member> optionalMember =
memberRepository.findById(memberId);
Member findMember =
optionalMember.orElseThrow(() ->
new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND));
return findMember;
}
private void verifyExistsEmail(String email) {
Optional<Member> member = memberRepository.findByEmail(email);
if (member.isPresent())
throw new BusinessLogicException(ExceptionCode.MEMBER_EXISTS);
}
}
StampService
package com.springboot.member.service;
import com.springboot.member.entity.Member;
import com.springboot.member.entity.Stamp;
import com.springboot.member.repository.MemberRepository;
import com.springboot.order.entity.Order;
public class StampService {
private MemberRepository memberRepository;
public StampService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
public int updateStamps(Order order) {
Member member = memberRepository.findById(order.getMember().getMemberId())
.orElseThrow(() -> new IllegalArgumentException("Member Not Found"));
int additionalStamps = order.getOrderCoffees().stream()
.mapToInt(orderCoffee -> orderCoffee.getQuantity())
.sum();
if (member.getStamp() == null) {
member.setStamp(new Stamp());
}
Stamp stamp = member.getStamp();
stamp.setStampCount(stamp.getStampCount() + additionalStamps);
memberRepository.save(member);
return additionalStamps;
}
}
OrderController
package com.springboot.order.controller;
import com.springboot.coffee.service.CoffeeService;
import com.springboot.order.dto.OrderPatchDto;
import com.springboot.order.dto.OrderPostDto;
import com.springboot.order.entity.Order;
import com.springboot.order.mapper.OrderMapper;
import com.springboot.order.service.OrderService;
import com.springboot.response.MultiResponseDto;
import com.springboot.response.SingleResponseDto;
import com.springboot.utils.UriCreator;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Positive;
import java.net.URI;
import java.util.List;
@RestController
@RequestMapping("/v11/orders")
@Validated
public class OrderController {
private final static String ORDER_DEFAULT_URL = "/v11/orders";
private final OrderService orderService;
private final OrderMapper mapper;
public OrderController(OrderService orderService, OrderMapper mapper) {
this.orderService = orderService;
this.mapper = mapper;
}
@PostMapping
public ResponseEntity postOrder(@Valid @RequestBody OrderPostDto orderPostDto) {
Order order = orderService.createOrder(mapper.orderPostDtoToOrder(orderPostDto));
URI location = UriCreator.createUri(ORDER_DEFAULT_URL, order.getOrderId());
return ResponseEntity.created(location).build();
}
@PatchMapping("/{order-id}")
public ResponseEntity patchOrder(@PathVariable("order-id") @Positive long orderId,
@Valid @RequestBody OrderPatchDto orderPatchDto) {
orderPatchDto.setOrderId(orderId);
Order order = orderService.updateOrder(mapper.orderPatchDtoToOrder(orderPatchDto));
return new ResponseEntity<>(null);
}
@GetMapping("/{order-id}")
public ResponseEntity getOrder(@PathVariable("order-id") @Positive long orderId) {
Order order = orderService.findOrder(orderId);
// TODO JPA 기능에 맞춰서 회원이 주문한 커피 정보를 ResponseEntity 에 포함 시키세요.
return new ResponseEntity<>(new SingleResponseDto<>(
mapper.orderToOrderResponseDto(order)), HttpStatus.OK);
}
@GetMapping
public ResponseEntity getOrders(@Positive @RequestParam int page,
@Positive @RequestParam int size) {
Page<Order> pageOrders = orderService.findOrders(page - 1, size);
List<Order> orders = pageOrders.getContent();
// TODO JPA 기능에 맞춰서 회원이 주문한 커피 정보 목록을 ResponseEntity 에 포함 시키세요.
return new ResponseEntity<>(new MultiResponseDto<>(
mapper.ordersToOrderResponseDtos(orders), pageOrders), HttpStatus.OK);
}
@DeleteMapping("/{order-id}")
public ResponseEntity cancelOrder(@PathVariable("order-id") @Positive long orderId) {
orderService.cancelOrder(orderId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
OrderCoffeeResponseDto
package com.springboot.order.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class OrderCoffeeResponseDto {
private long coffeeId;
private String korName;
private String engName;
private Integer price;
private Integer quantity;
}
Order entity
package com.springboot.order.entity;
import com.springboot.member.entity.Member;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@NoArgsConstructor
@Getter
@Setter
@Entity(name = "ORDERS")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ORDERS_ID")
private Long orderId;
@Enumerated(EnumType.STRING)
private OrderStatus orderStatus = OrderStatus.ORDER_REQUEST;
@Column(nullable = false)
private LocalDateTime createdAt = LocalDateTime.now();
@Column(nullable = false, name = "LAST_MODIFIED_AT")
private LocalDateTime modifiedAt = LocalDateTime.now();
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
// 데이터베이스에 Order 를 추가할때 OrderCoffee 도 추가되게 함 (영속성 같이 등록)
@OneToMany(mappedBy = "order", cascade = CascadeType.PERSIST)
private List<OrderCoffee> orderCoffees = new ArrayList<>();
public void setOrderCoffee(OrderCoffee orderCoffee) {
orderCoffees.add(orderCoffee);
if (orderCoffee.getOrder() != this) {
orderCoffee.setOrder(this);
}
}
public void setMember(Member member) {
this.member = member;
if (!member.getOrders().contains(this)) {
member.setOrder(this);
}
}
public void addMember(Member member) {
this.member = member;
}
public enum OrderStatus {
ORDER_REQUEST(1, "주문 요청"),
ORDER_CONFIRM(2, "주문 확정"),
ORDER_COMPLETE(3, "주문 처리 완료"),
ORDER_CANCEL(4, "주문 취소");
@Getter
private int stepNumber;
@Getter
private String stepDescription;
OrderStatus(int stepNumber, String stepDescription) {
this.stepNumber = stepNumber;
this.stepDescription = stepDescription;
}
}
}
OrderCoffee entity
package com.springboot.order.entity;
import com.springboot.coffee.entity.Coffee;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Getter
@Setter
@NoArgsConstructor
@Entity(name = "ORDER_COFFEE")
public class OrderCoffee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderCoffeeId;
@Column(nullable = false)
private int quantity;
@ManyToOne
@JoinColumn(name = "ORDERS_ID")
private Order order;
@ManyToOne
@JoinColumn(name = "COFFEE_ID")
private Coffee coffee;
public OrderCoffee(int quantity, Coffee coffee, Order order) {
this.quantity = quantity;
this.coffee = coffee;
this.order = order;
}
public void setOrder(Order order) {
this.order = order;
if (!order.getOrderCoffees().contains(this)) {
order.getOrderCoffees().add(this);
}
}
}
OrderMapper
package com.springboot.order.mapper;
import com.springboot.coffee.entity.Coffee;
import com.springboot.member.entity.Member;
import com.springboot.order.dto.OrderCoffeeResponseDto;
import com.springboot.order.dto.OrderPatchDto;
import com.springboot.order.dto.OrderPostDto;
import com.springboot.order.dto.OrderResponseDto;
import com.springboot.order.entity.Order;
import com.springboot.order.entity.OrderCoffee;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import java.util.List;
import java.util.stream.Collectors;
@Mapper(componentModel = "spring")
public interface OrderMapper {
default Order orderPostDtoToOrder(OrderPostDto orderPostDto) {
// 새로운 Order 객체를 생성
Order order = new Order();
// 새로운 Member 객체를 생성하고, orderPostDto 에서 memberId를 설정
Member member = new Member();
member.setMemberId(orderPostDto.getMemberId());
// 생성한 회원 객체를 주문 객체에 설정
order.setMember(member);
// 주문 Dto 에 포함된 커피 주문 목록을 가져와서 새로운 OrderCoffee 목록을 만들기
List<OrderCoffee> orderCoffees = orderPostDto.getOrderCoffees().stream()
.map(orderCoffeeDto -> {
// 새로운 OrderCoffee 객체를 생성하고, 수량을 설정합니다.
OrderCoffee orderCoffee = new OrderCoffee();
orderCoffee.setQuantity(orderCoffeeDto.getQuantity());
// 새로운 Coffee 객체를 생성하고, 커피 ID를 설정합니다.
Coffee coffee = new Coffee();
coffee.setCoffeeId(orderCoffeeDto.getCoffeeId());
// 생성한 Coffee 객체를 OrderCoffee 객체에 설정합니다.
orderCoffee.setCoffee(coffee);
// OrderCoffee 객체에 주문(Order) 객체를 설정합니다.
orderCoffee.setOrder(order);
// OrderCoffee 객체를 반환합니다.
return orderCoffee;
}).collect(Collectors.toList());
// 생성한 OrderCoffee 목록을 주문(Order) 객체에 설정합니다.
order.setOrderCoffees(orderCoffees);
// 최종적으로 완성된 주문(Order) 객체를 반환합니다.
return order;
}
Order orderPatchDtoToOrder(OrderPatchDto orderPatchDto);
@Mapping(source = "member.memberId", target = "memberId")
OrderResponseDto orderToOrderResponseDto(Order order);
List<OrderResponseDto> ordersToOrderResponseDtos(List<Order> orders);
// default OrderCoffeeResponseDto orderCoffeeToOrderCoffeeResponseDto(OrderCoffee orderCoffee) {
// OrderCoffeeResponseDto orderCoffeeResponseDto = new OrderCoffeeResponseDto();
// orderCoffeeResponseDto.setQuantity(orderCoffeeResponseDto.getQuantity());
// Coffee coffee = orderCoffee.getCoffee();
// orderCoffeeResponseDto.setCoffeeId(coffee.getCoffeeId());
// orderCoffeeResponseDto.setKorName(coffee.getKorName());
// orderCoffeeResponseDto.setEngName(coffee.getEngName());
// orderCoffeeResponseDto.setPrice(coffee.getPrice());
// return orderCoffeeResponseDto;
// }
@Mapping(source = "coffee.coffeeId", target = "coffeeId")
@Mapping(source = "coffee.korName", target = "korName")
@Mapping(source = "coffee.engName", target = "engName")
@Mapping(source = "coffee.price", target = "price")
OrderCoffeeResponseDto orderCoffeeToOrderCoffeeResponseDto(OrderCoffee orderCoffee);
}
OrderService
package com.springboot.order.service;
import com.springboot.coffee.service.CoffeeService;
import com.springboot.exception.BusinessLogicException;
import com.springboot.exception.ExceptionCode;
import com.springboot.member.entity.Member;
import com.springboot.member.entity.Stamp;
import com.springboot.member.service.MemberService;
import com.springboot.order.entity.Order;
import com.springboot.order.repository.OrderRepository;
import com.springboot.order.repository.StampRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Optional;
@Service
public class OrderService {
private final MemberService memberService;
private final OrderRepository orderRepository;
private final CoffeeService coffeeService;
public OrderService(MemberService memberService, OrderRepository orderRepository, CoffeeService coffeeService) {
this.memberService = memberService;
this.orderRepository = orderRepository;
this.coffeeService = coffeeService;
}
public Order createOrder(Order order) {
//회원과 커피가 존재하는지 확인
verifyOrder(order);
// 주문 시킨 커피의 수량만큼 스탬프 증가
updateStamp(order);
// int currentStampCount = order.getMember().getStamp().getStampCount();
// // stream으로 돌면 람다식에서 외부 변수를 못 쓰므로 for-each로 작성
// for (OrderCoffee orderCoffee : order.getOrderCoffees()) {
// currentStampCount += orderCoffee.getQuantity();
// }
// order.getMember().getStamp().setStampCount(currentStampCount);
return orderRepository.save(order);
}
// 메서드 추가
public Order updateOrder(Order order) {
Order findOrder = findVerifiedOrder(order.getOrderId());
Optional.ofNullable(order.getOrderStatus())
.ifPresent(orderStatus -> findOrder.setOrderStatus(orderStatus));
findOrder.setModifiedAt(LocalDateTime.now());
return orderRepository.save(findOrder);
}
public Order findOrder(long orderId) {
return findVerifiedOrder(orderId);
}
public Page<Order> findOrders(int page, int size) {
return orderRepository.findAll(PageRequest.of(page, size,
Sort.by("orderId").descending()));
}
public void cancelOrder(long orderId) {
Order findOrder = findVerifiedOrder(orderId);
int step = findOrder.getOrderStatus().getStepNumber();
// OrderStatus 의 step 이 2 이상일 경우(ORDER_CONFIRM)에는 주문 취소가 되지 않도록한다.
if (step >= 2) {
throw new BusinessLogicException(ExceptionCode.CANNOT_CHANGE_ORDER);
}
findOrder.setOrderStatus(Order.OrderStatus.ORDER_CANCEL);
findOrder.setModifiedAt(LocalDateTime.now());
orderRepository.save(findOrder);
}
private Order findVerifiedOrder(long orderId) {
Optional<Order> optionalOrder = orderRepository.findById(orderId);
Order findOrder =
optionalOrder.orElseThrow(() ->
new BusinessLogicException(ExceptionCode.ORDER_NOT_FOUND));
return findOrder;
}
private void verifyOrder(Order order) {
// 회원이 존재하는지 확인
memberService.findVerifiedMember(order.getMember().getMemberId());
// TODO 커피가 존재하는지 조회하는 로직이 포함되어야 합니다.
order.getOrderCoffees().stream()
.forEach(orderCoffee -> coffeeService.findVerifiedCoffee
(orderCoffee.getCoffee().getCoffeeId()));
}
private void updateStamp(Order order) {
Member member = memberService.findMember(order.getMember().getMemberId());
// 주문 내역의 모든 주문 수량을 더한 값을 구함
/** orderStampCount
* {
* "memberId" : 1,
* "orderCoffees" : [
* {
* "coffeeId" : 1,
* "quantity" : 5
* },
* {
* "coffeeId" : 2,
* "quantity" : 2
* }
* ]
* } 위 데이터의 걍우 7을 구하게 됩니다.
*/
int orderStampCount = order.getOrderCoffees().stream()
.map(orderCoffee -> orderCoffee.getQuantity())
.mapToInt(quantity -> quantity)
.sum();
Stamp stamp = member.getStamp();
stamp.setStampCount(stamp.getStampCount() + orderStampCount);
stamp.setModifiedAt(LocalDateTime.now());
memberService.updateMember(member);
}
}