목표: 주문 API 만들기 실습
ERD
Entity
Order Entity는 아이디, 주문시간, 주문상태, 메모, 회원, 주문아이템을 필드로 갖으며 작성자와 생성시간을 제공하는 BaseEntity를 상속 받음
Order 엔티티에서 setMember와 addOrderItem 연관관계 편의 메서드를 제공
오더와 멤버는 다대일 관계
오더와 오더아이템은 일대다 관계
@Entity @Table(name = "orders") @Getter @Setter public class Order extends BaseEntity { @Id @Column(name = "id") private String uuid; @Column(name = "order_datetime", columnDefinition = "TIMESTAMP") private LocalDateTime orderDatetime; @Enumerated(EnumType.STRING) private OrderStatus orderStatus; @Lob private String memo; @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "member_id", referencedColumnName = "id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) private List<OrderItem> orderItems = new ArrayList<>(); public void setMember(Member member) { if(Objects.nonNull(this.member)) { this.member.getOrders().remove(this); } this.member = member; member.getOrders().add(this); } public void addOrderItem(OrderItem orderItem) { orderItem.setOrder(this); } }
Dto
dto 객체 만들어 통신
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderDto {
private String uuid;
private LocalDateTime orderDatetime;
private OrderStatus orderStatus;
private String memo;
private MemberDto memberDto;
private List<OrderItemDto> orderItemDtos;
}
Converter
Converter를 통해 엔티티를 DTO로, DTO를 엔티티로 변환
@Component
public class OrderConverter {
public Order convertOrder(OrderDto orderDto) {
Order order = new Order();
order.setUuid(orderDto.getUuid());
order.setMemo(orderDto.getMemo());
order.setOrderStatus(orderDto.getOrderStatus());
order.setOrderDatetime(LocalDateTime.now());
order.setCratedAt(LocalDateTime.now());
order.setCreatedBy(orderDto.getMemberDto().getName());
order.setMember(this.convertMember(orderDto.getMemberDto()));
this.convertOrderItems(orderDto).forEach(order::addOrderItem);
return order;
}
public OrderDto convertOrderDto (Order order) {
return OrderDto.builder()
.uuid(order.getUuid())
.memo(order.getMemo())
.orderStatus(order.getOrderStatus())
.orderDatetime(order.getOrderDatetime())
.memberDto(this.convertMemberDto(order.getMember()))
.orderItemDtos(order.getOrderItems().stream()
.map(this::convertOrderItemDto)
.collect(Collectors.toList())
)
.build();
}
}
주문 저장
entity를 트랜잭션 밖으로 보내는 것 좋지 않음, dto 객체 만들어 통신
@Transactional
public String save(OrderDto dto) {
//1. dto -> entity 변환(준영속)
Order order = orderConverter.convertOrder(dto);
//2. orderRepository.save(entity)-> 영속화
Order entity = orderRepository.save(order);
//3. 결과 반환
return entity.getUuid();
}
주문 조회
@Transactional
public OrderDto findOne(String uuid) throws NotFoundException {
//1. 조회를 위한 키값 인자로 받기
//2. orderRepository.findById(uuid)-> 조회(영속화된 엔티티)
return orderRepository.findById(uuid)
.map(orderConverter::convertOrderDto)//3. entity -> dto
.orElseThrow(() -> new NotFoundException("주문을 찾을 수 없습니다."));
}
@Transactional
public Page<OrderDto> findAll(Pageable pageable) {
return orderRepository.findAll(pageable)
.map(orderConverter::convertOrderDto);
}
API 전송 객체
컨트롤러에서 API 전송 객체에 담아서 결과 반환
@Getter
@Setter
@NoArgsConstructor
public class ApiResponse<T> {
private int statusCode;
private T data;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime serverDatetime;
public ApiResponse(int statusCode, T data) {
this.statusCode = statusCode;
this.data = data;
this.serverDatetime = LocalDateTime.now();
}
public static <T> ApiResponse<T> ok(T data) {
return new ApiResponse<>(200, data);
}
public static <T> ApiResponse<T> fail(int statusCode, T errData) {
return new ApiResponse<>(statusCode, errData);
}
}
Controller
컨트롤러에서 호출
@PostMapping("/orders")
public ApiResponse<String> save(@RequestBody OrderDto orderDto) {
return ApiResponse.ok(orderService.save(orderDto));
}
@프로그래머스 미니 데브코스 & CNU SW Academy 강의 내용 정리
'모각코' 카테고리의 다른 글
[모각코 8회차] Spring Security with JWT (0) | 2022.08.25 |
---|---|
[모각코 7회차] Spring Security Internals (0) | 2022.08.19 |
[모각코 5회차] SPA와 CORS (0) | 2022.08.04 |
[모각코 4회차] 스프링 AOP와 트랜잭션 (0) | 2022.07.29 |
[모각코 3회차] logback 설정 (0) | 2022.07.22 |