Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- springdatajpa
- kotlin
- JDBC
- http
- Servlet
- SpringBoot
- Exception
- 스프링 핵심 기능
- 인프런
- Proxy
- 자바
- pointcut
- 알고리즘
- 그리디
- java
- AOP
- jpa
- Greedy
- 백준
- QueryDSL
- db
- spring
- Android
- 스프링
- Spring Boot
- 스프링 핵심 원리
- transaction
- JPQL
- 김영한
- Thymeleaf
Archives
- Today
- Total
개발자되기 프로젝트
주문 도메인 개발 본문
1. 구현 기능
- 상품 주문
- 주문 내역 조회
- 주문 취소
2. 순서
- 주문 엔티티, 주문상품 엔티티 개발
- 주문 repository 개발
- 주문 service 개발
- 주문 검색 기능 개발
- 주문 기능 test
3. 주문 Entity
- Order는 Member, Delivery, OrderItemd와 연관관계가 있음
- OrderItem은 list로 가지고 있음.(OrderItem이 연관관계주인)
- Order는 OrderItem을 읽어오기만 함.
- Order가 생성될 때 Member, Delivery, OrdeItems 필요함.
- 생성 메서드를 통해 한 번에 세팅하자.
- 생성메서드가 가능한 이유는
- Order가 컨트롤 하는 쪽이기 때문에 양방향으로 연관관계를 맺어주는 편의메서드가 있기 때문.
//==생성메서드==// //order가 핵심임. 연관관계 편의 메서드가 order에 있어서 가능함. 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; }
- OrderClass
@Entity @Table(name="orders") @Getter public class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) //order_item의 어느 컬럼으로부터 orderItem 읽어옴? private List<OrderItem> orderItems = new ArrayList<>(); @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "delivery_id") private Delivery delivery; public void setOrderDate(LocalDateTime orderDate) { this.orderDate = orderDate; } private LocalDateTime orderDate; //주문 시간 @Enumerated(EnumType.STRING) private OrderStatus status; //주문상태, enum public void setStatus(OrderStatus status) { this.status = status; } //양방향 연관관꼐 편의 메서드// //양방향 연관관계는 객체를 양방향으로 넣어줗어야함. //요렇게하면 실수도 줄이고 간단해짐.ㅋㅋ //어디에 있으면 좋아? 컨트롤 하는 쪽 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); } //==생성메서드==// //order가 핵심임. 연관관계 편의 메서드가 order에 있어서 가능함. 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) { //주문의 주문 아이템들에 대해서 CANCEL 처리 orderItem.cancel(); } } //==조회 로직==// /** * 전체 주문가격 조회 */ public int getTotalPrice(){ int totalPrice = 0; for (OrderItem orderItem : orderItems) { totalPrice += orderItem.getTotalPrice(); } return totalPrice; } }
4. OrderItem class
- 주문, 주문 취소에 따라 item의 stockQuantity가 변경되어야함.
- 해당 아이템의 총 주문금액 반환
- OrderItem와 Item은 단방향 다대일 연관관계. OrderItem이 Item을 참조함.
- OrderItem생성시 Item, 주문가격, 수량 등이 필요함.
- 생성메서드를 통해 처리.
@Entity
@Getter
@Setter
public class OrderItem {
@Id
@GeneratedValue
@Column(name = "order_item_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id") //Item의 PK를 FK로
private Item item;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id")
private Order order;
private int orderPrice; //주문 금액
private int count; //주문 수량
//==생성 메서드==//
public static OrderItem createOrderItem(Item item, int orderPrice, int count){
OrderItem orderItem = new OrderItem();
orderItem.setItem(item);
orderItem.setOrderPrice(orderPrice);
orderItem.setCount(count);
item.removeStock(count);
return orderItem;
}
//==비즈니스 로직==//
/**
* 주문수량 원복.
*/
public void cancel() {
getItem().addStock(count);
}
/**
* 해당 item의 총 주문가격.
*/
public int getTotalPrice() {
return getOrderPrice() * getCount();
}
}
5. GitHub : 210806 Order Entity
6. 생성메서드
- 생성메서드는 static으로 해야함.
- 왜냐? 외부에서 바로 생성매서드를 통해 객체 생성이 필요함.
- 클래스 레벨에서 바로 사용가능.
//==생성메서드==//
//order가 핵심임. 연관관계 편의 메서드가 order에 있어서 가능함.
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;
}
- 사용
//주문 생성
Order order = Order.createOrder(member, delivery, orderItem);
- 생성자가 아니라 별도의 생성 메서드를 사용하는 경우
- 기본 생성자를 통해 생성하지 못하도록 protected로 막아야 한다.
/**
* 기본 생성자 사용 안함.
*/
protected Order() {
}
- JPA에서 protected는 사용하지 말라는 의미.
(JAVA : 동일 패키지내의 클래스, 해당 클래스를 상속받은 외부 패키지의 클래스만 접근 허용)
'인프런 > [인프런] Springboot와 JPA활용 1' 카테고리의 다른 글
주문 기능 테스트 (0) | 2021.08.06 |
---|---|
주문 repository, Service (0) | 2021.08.06 |
상품 domain, repository, service개발 (0) | 2021.08.06 |
회원 기능 테스트 (0) | 2021.08.06 |
MemberService 개발 (0) | 2021.08.06 |
Comments