반응형

본 내용은 인프런의 이도원 님의 강의 "Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)" 내용을 바탕으로 정리한 내용입니다.

 

OrderService 생성

  • Framework: Spring Boot 3.2.6
  • Java Version: 17
  • Project Name: OrderService
  • Dependencies:
    • Spring Boot DevTools
    • Lombok
    • Spring Web
    • Spring Data JPA
    • Eureka Discovery Client
    • ModelMapper

OrderService 기능

  • 사용자 별 상품 주문
  • 사용자 별 주문 내역 조회

설정 파일 수정

pom.xml 수정

<dependency>  
    <groupId>org.modelmapper</groupId>  
    <artifactId>modelmapper</artifactId>  
    <version>2.3.8</version>  
</dependency>
  • ModelMapper 의존성 추가

application.yml 수정

server:  
  port: 0 # port  

spring:  
  application:  
    name: OrderService  
  datasource:  
    driverClassName: org.mariadb.jdbc.Driver  
    url: jdbc:mariadb://localhost:3306/shop_db?characterEncoding=UTF-8&serverTimezone=UTC  
    username: root  
    password: 1234  
  jpa:  
    hibernate:  
      #ddl-auto: update  
      ddl-auto: create-drop  
    properties:  
      hibernate:  
        show_sql: true  
        format_sql: true  
        use_sql_comments: true  
eureka:  
  client:  
    service-url:  
      defaultZone: http://localhost:8761/eureka  

logging:  
  level:  
    com.example.OrderService: DEBUG
  • Dynamic Port 설정: server.port=0 (애플리케이션 시작 시 랜덤 포트 할당)
  • Eureka 클라이언트 설정: eureka.client.service-url.defaultZone=http://localhost:8761/eureka
  • JPA 설정
    • Hibernate DDL 자동 실행: ddl-auto=create-drop (애플리케이션 실행 시 DB 테이블 초기화)
    • SQL 출력: hibernate.show_sql=true, hibernate.format_sql=true

JPA 관련 파일 생성

OrderEntity 생성

package com.example.OrderService.jpa;  

import jakarta.persistence.*;  
import lombok.Data;  
import org.hibernate.annotations.ColumnDefault;  

import java.util.Date;  

@Data  
@Entity  
@Table(name="orders")  
public class OrderEntity {  
    @Id  
    @GeneratedValue    private long id;  

    @Column(nullable = false, length = 120)  
    private String productId;  
    @Column(nullable = false)  
    private Integer qty;  
    @Column(nullable = false)  
    private Integer unitPrice;  
    @Column(nullable = false)  
    private Integer totalPrice;  

    @Column(nullable = false)  
    private String userId;  
    @Column(nullable = false, unique = true)  
    private String orderId;  

    @Column(nullable = false, updatable = false, insertable = false)  
    @ColumnDefault( value = "CURRENT_TIMESTAMP")  
    private Date createAt;  
}
  • 주문 데이터를 저장하는 테이블과 매핑

OrderRepository

package com.example.OrderService.jpa;  

import org.springframework.data.repository.CrudRepository;  

public interface OrderRepository extends CrudRepository<OrderEntity, Long> {  
    OrderEntity findByOrderId(String orderId);  
    Iterable<OrderEntity> findByUserId(String userId);  
}
  • 기능: 데이터베이스 연동
  • 주요 메서드
    • findByOrderId(String orderId): 특정 주문 조회
    • findByUserId(String userId): 특정 사용자의 주문 상품 조회

Service 추가

  • 비즈니스 로직

OrderService

package com.example.OrderService.service;  

import com.example.OrderService.dto.OrderDto;  
import com.example.OrderService.jpa.OrderEntity;  

public interface OrderService {  
    OrderDto createOrder(OrderDto orderDetails);  
    OrderDto getOrderByOrderId(String orderId);  
    Iterable<OrderEntity> getOrdersByUserId(String userId);  
}

OrderServiceImpl

package com.example.OrderService.service;  

import com.example.OrderService.dto.OrderDto;  
import com.example.OrderService.jpa.OrderEntity;  
import com.example.OrderService.jpa.OrderRepository;  
import org.modelmapper.ModelMapper;  
import org.modelmapper.convention.MatchingStrategies;  
import org.springframework.core.env.Environment;  
import org.springframework.stereotype.Service;  

import java.util.UUID;  

@Service  
public class OrderServiceImpl implements  OrderService{  

    private OrderRepository repository;  
    private Environment env;  

    public OrderServiceImpl(OrderRepository repository, Environment env){  
        this.repository = repository;  
        this.env = env;  
    }  

    /**  
     * 상품 주문  
     * @param orderDto  
     * @return  
     */  
    @Override  
    public OrderDto createOrder(OrderDto orderDto) {  
        orderDto.setOrderId(UUID.randomUUID().toString());  
        orderDto.setTotalPrice(orderDto.getQty() * orderDto.getUnitPrice());  

        ModelMapper modelMapper = new ModelMapper();  
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);  

        OrderEntity orderEntity = modelMapper.map(orderDto, OrderEntity.class);  

        repository.save(orderEntity);  

        OrderDto returnValue = modelMapper.map(orderEntity, OrderDto.class);  
        return returnValue;  
    }  

    /**  
     * 주문 정보 상세 조회  
     * @param orderId  
     * @return  
     */  
    @Override  
    public OrderDto getOrderByOrderId(String orderId) {  
        OrderEntity orderEntity = repository.findByOrderId(orderId);  
        OrderDto orderDto = new ModelMapper().map(orderEntity, OrderDto.class);  
        return orderDto;  
    }  

    /**  
     * 사용자별 주문 조회  
     * @param userId  
     * @return  
     */  
    @Override  
    public Iterable<OrderEntity> getOrdersByUserId(String userId) {  
        return repository.findByUserId(userId);  
    }  
}0
  • 기능: 비즈니스 로직 처리
  • 주요 메서드
    • createOrder(): 주문 데이터를 받아 DB에 저장하고 결과를 반환
    • getOrderByOrderId(String orderId): 주문 ID를 기반으로 주문 상세 정보를 조회
    • getOrdersByUserId(): 사용자 ID를 기반으로 해당 사용자의 모든 주문을 조회

Dto 추가

  • 주문 정보를 담은 객체

OrderDto

package com.example.OrderService.dto;  

import lombok.Data;  

import java.io.Serializable;  

@Data  
public class OrderDto implements Serializable {  
    private String productId;  
    private Integer qty;  
    private Integer unitPrice;  
    private Integer totalPrice;  

    private String orderId;  
    private String userId;  
}

OrderRepository

package com.example.OrderService.jpa;  

import org.springframework.data.repository.CrudRepository;  

public interface OrderRepository extends CrudRepository<OrderEntity, Long> {  
    OrderEntity findByOrderId(String orderId);  
    Iterable<OrderEntity> findByUserId(String userId);  
}

VO 추가

  • 클라이언트와 서버 사이에 주고받는 정보를 담을 객체

RequestOrder

package com.example.OrderService.vo;  

import lombok.Data;  

import java.util.Date;  

@Data  
public class RequestOrder {  
    private String productId;  
    private Integer qty;  
    private Integer unitPrice;  
    private Integer totalPrice;  
    private Date createdAt;  

    private String orderId;  
}

ResponseOrder

package com.example.OrderService.vo;  

import com.fasterxml.jackson.annotation.JsonInclude;  
import lombok.Data;  

import java.util.Date;  

@Data  
@JsonInclude(JsonInclude.Include.NON_NULL)  
public class ResponseOrder {  
    private String productId;  
    private Integer qty;  
    private Integer unitPrice;  
    private Integer totalPrice;  
    private Date createdAt;  

    private String orderId;  
}

Controller 추가

  • View에서 요청한 정보를 서버에서 받아 Service를 호출한다.

OrderController

package com.example.OrderService.controller;  

import com.example.OrderService.dto.OrderDto;  
import com.example.OrderService.jpa.OrderEntity;  
import com.example.OrderService.service.OrderService;  
import com.example.OrderService.vo.RequestOrder;  
import com.example.OrderService.vo.ResponseOrder;  
import org.modelmapper.ModelMapper;  
import org.modelmapper.convention.MatchingStrategies;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.core.env.Environment;  
import org.springframework.http.HttpStatus;  
import org.springframework.http.ResponseEntity;  
import org.springframework.stereotype.Controller;  
import org.springframework.web.bind.annotation.GetMapping;  
import org.springframework.web.bind.annotation.PathVariable;  
import org.springframework.web.bind.annotation.PostMapping;  
import org.springframework.web.bind.annotation.RequestBody;  

import java.util.ArrayList;  
import java.util.List;  

@Controller
@RequestMapping("/orderService")
public class OrderController {  
    private Environment env;  
    private OrderService orderService;  

    @Autowired  
    public OrderController(Environment env, OrderService orderService){  
        this.env = env;  
        this.orderService = orderService;  
    }  

    /**  
     * 상품 주문  
     * @param userId  
     * @param orderDetails  
     * @return  
     */  
    @PostMapping(value="/{userId}/orders")  
    public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId  
            , @RequestBody RequestOrder orderDetails){  
        ModelMapper modelMapper = new ModelMapper();  
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);  

        OrderDto orderDto = modelMapper.map(orderDetails, OrderDto.class);  
        orderDto.setUserId(userId);  
        OrderDto createDto = orderService.createOrder(orderDto);  
        ResponseOrder returnValue = modelMapper.map(createDto, ResponseOrder.class);  

        return ResponseEntity.status(HttpStatus.CREATED).body(returnValue);  
    }  

    /**  
     * 사용자 별 주문내역 조회  
     * @param userId  
     * @return  
     */  
    @GetMapping(value="/{userId}/orders")  
    public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId) {  
        Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId);  

        List<ResponseOrder> result = new ArrayList<>();  
        orderList.forEach(v->{  
            result.add(new ModelMapper().map(v,ResponseOrder.class));  
        });  

        return ResponseEntity.status(HttpStatus.OK).body(result);  
    }  
}
  • 역할: HTTP 요청을 처리하고 응답 반환
  • 주요 엔드포인트
    • /createOrder: 클라이언트가 주문 정보를 제공하면 주문을 생성하고 결과를 반환
    • /getOrder: 특정 사용자 userId의 모든 주문 내역을 조회하여 반환.

결과

주문 정보 등록

[
    {
        "productId": "CATALOG-1",
        "qty": 10,
        "unitPrice": 900,
        "totalPrice": 9000,
        "orderId": "5b3d9b1f-2a75-4a97-94e5-2c3d931e1c57"
    }
]
반응형

+ Recent posts