728x90
주문 Repository 개발

- 1. save 메서드
- Order를 저장한다.
- 2.findOne 메서드
- id값으로 Order를 찾는다.
- 후에 findAll 메서드로 검색조건에 맞는 검색된 데이터를 출력할 것이다(동적 쿼리가 들어가야 해서 나중에...)
주문 Service 개발
@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);
//다른 로직에서 내가 만든 createOrderItem을 사용하는것이 아니라, setter로 만들수도 있다.
//OrderItem o = new OrderItem();//에러 발생
//주문 생성
Order order = Order.createOrder(member,delivery,orderItem);
//주문 저장
//cascade 옵션 때문에 order를 persist 하면 연관된 컬럼도 persist 해준다
//cascade는 다른곳에서 참조할수 없는 곳에서 사용하는 것이 좋다.
//현재는 order만 orderItem,delivery 를 사용하기 때문에 cascade 옵션을 사용한다.
orderRepository.save(order);
return order.getId();
}
/**
* 주문 취소
*/
@Transactional
public void cancelOrder(Long orderId) {
//주문 엔티티 조회
Order order = orderRepository.findOne(orderId);
//주문 취소
order.cancel();
//SQL을 직접 사용하는 라이브러리 같은경우 직접 쿼리를 작성하고 업데이트를 해줘야 하지만 JPA는 더티체크를 해서 변경된 부분을 알아서 변경해 주기 때문에 훨씬 로직이 간단해 진다.
}
/**
* 검색
*/
/*
public List<Order> findOrders(OrderSearch orderSearch){
return orderRepository.findOne(orderSearch);
}
*/
}
- order 메서드
- 주문을 해주는 메서드이다.
- memberId와 itemId , count를 받으므로 member와 item을 조회를 해주어야 한다.
- 배송정보를 생성해 준 뒤, 주문 상품을 생성해준다(createOrderItem)
- 참고) createOrderItem 메서드 같은 경우 내가 만든 로직이니까 orderItem을 생성할 때, 이 메서드를 사용하겠지만 다른 사람이 유지보수할 때에는 해당 메소드를 안 보고 getter, setter를 통해 생성할 수도 있다.
- 이를 방지하기 위해 JPA는 protected까지 허용해 주기 때문에 protected로 기본 생성자를 막는다.
둘 중 편한 방법을 사용해서 막으면 된다.
public class OrderItem {
// protected로 기본생성자 막는다
protected OrderItem(){
}
}

- 주문을 생성해 준다(createOrder)
위와 마찬가지로 protected로 생성자를 막아준다

- 주문을 저장한다.
- 현재 Order 엔티티의 orderItem, delivery에 cascade 옵션이 걸려있기 때문에 order를 저장할 때, 더티 체크를 하여 변경된 모든 엔티티를 insert 해준다.
- cancelOrder 메서드
- 주문 엔티티를 조회한 뒤, 주문 취소(cancel) 메서드를 호출한다.
- 기존 mybatis, jdbc template 같은 직접 sql을 작성하는 라이브러리를 사용했을 경우 주문 취소 로직에 재고를 증가시켜주는 쿼리를 실행하는 부분을 for문으로 실행시켜 주어야 하지만 JPA를 사용하면 엔티티에서 재고를 for문으로 변경해주면 영속성 컨택스트가 알아서 변경된 부분을 더티 체크로 찾아서 업데이트 쿼리를 실행시켜준다.
참고: 주문 서비스의 주문과 주문 취소 메서드를 보면 비즈니스 로직 대부분이 엔티티에 있다.
- 서비스 계층 은 단순히 엔티티에 필요한 요청을 위임하는 역할을 한다.
- 이처럼 엔티티가 비즈니스 로직을 가지고 객체 지 향의 특성을 적극 활용하는 것을 도메인 모델 패턴(http://martinfowler.com/eaaCatalog/ domainModel.html)이라 한다.
- 반대로 엔티티에는 비즈니스 로직이 거의 없고 서비스 계층에서 대부분 의 비즈니스 로직을 처리하는 것을 트랜잭션 스크립트 패턴(http://martinfowler.com/eaaCatalog/ transactionScript.html)이라 한다.
- 어떤 패턴이 유지 보수가 좋은지를 판단하여 사용하는 것이 가장 좋다.
728x90
'실전! 스프링 부트와 JPA 활용1(웹 애플리케이션 개발)' 카테고리의 다른 글
| Ch06. 상품 도메인 개발 - 주문 검색 기능 개발 (0) | 2021.12.06 |
|---|---|
| Ch06. 상품 도메인 개발 - 주문 기능 테스트 (0) | 2021.12.06 |
| Ch06. 주문 도메인 개발 - 주문, 주문상품 엔티티 개발 (0) | 2021.12.06 |
| Ch05. 상품 도메인 개발 - 상품 Service 개발 (0) | 2021.12.05 |
| Ch05. 상품 도메인 개발 - 상품 Repository 개발 (0) | 2021.12.05 |