스프링 부트와 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 메서드를 호출할 수 있는 것이 신기했다.