Dependency 추가
➡ DevTools, Lombok, Web, Eureka Discovery Client, H2 Database,
ModelMapper, Spring Data JPA
pom.xml 수정
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.8</version>
</dependency>
package com.example.orderserivce;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class OrderSerivceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderSerivceApplication.class, args);
}
}
spring:
application:
name: order-service
h2:
console:
enabled: true
settings:
web-allow-others: true
path: /h2-console
jpa:
hibernate:
ddl-auto: update
database: h2
defer-datasource-initialization: true
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testdb
server:
port: 0
eureka:
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
logging:
level:
com.example.orderserivce: DEBUG
package com.example.orderserivce.jpa;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.ColumnDefault;
import java.io.Serializable;
import java.util.Date;
@Data
@Entity
@Table(name="orders")
public class OrderEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
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 createdAt;
}
💡 직렬화(Serializable) 사용 이유
가지고 있는 Object를 다른 네트워크로 전송하거나 데이터베이스에 보관하기 위해서
package com.example.orderserivce.jpa;
import org.springframework.data.repository.CrudRepository;
public interface OrderRepository extends CrudRepository<OrderEntity, Long> {
OrderEntity findByOrderId(String orderId);
Iterable<OrderEntity> findByUserId(String userId);
}
package com.example.orderserivce.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;
}
package com.example.orderserivce.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 cratedAt;
private String orderId;
}
package com.example.orderserivce.service;
import com.example.orderserivce.dto.OrderDto;
import com.example.orderserivce.jpa.OrderEntity;
public interface OrderService {
OrderDto createOrder(OrderDto orderDetails);
OrderDto getOrderByOrderId(String orderId);
Iterable<OrderEntity> getAllOrdersByUserId(String userId);
}
package com.example.orderserivce.service;
import com.example.orderserivce.dto.OrderDto;
import com.example.orderserivce.jpa.OrderEntity;
import com.example.orderserivce.jpa.OrderRepository;
import com.netflix.discovery.converters.Auto;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import java.util.UUID;
@Service
public class OrderServiceImpl implements OrderService {
OrderRepository orderRepository;
@Autowired
public OrderServiceImpl(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public OrderDto createOrder(OrderDto orderDetails) {
orderDetails.setOrderId(UUID.randomUUID().toString());
orderDetails.setTotalPrice(orderDetails.getTotalPrice()*orderDetails.getUnitPrice());
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderEntity orderEntity = mapper.map(orderDetails, OrderEntity.class);
orderRepository.save(orderEntity);
OrderDto returnValue = mapper.map(orderEntity, OrderDto.class);
return returnValue;
}
@Override
public OrderDto getOrderByOrderId(String orderId) {
OrderEntity orderEntity = orderRepository.findByOrderId(orderId);
OrderDto orderDto = new ModelMapper().map(orderEntity, OrderDto.class);
return orderDto;
}
@Override
public Iterable<OrderEntity> getAllOrdersByUserId(String userId) {
return orderRepository.findByUserId(userId);
}
}
💡 Dto와 Entity의 차이
Entity는 데이터베이스와의 직접적인 연관이 있는 객체이며, 데이터베이스에서 데이터를 가져오거나 저장할 때 사용DTO는 데이터를 효율적으로 전송하기 위해 필요한 값만 포함한 객체이며, 서비스나 컨트롤러 간에 데이터를 주고 받을 때 사용하고, 필요에 따라 Entity에서 필요한 정보를 뽑아 전달- 둘은 서로 보완적인 역할을 하며, 다양한 계층 간에 데이터를 전송하고 관리하는데 중요한 역할
구분 Entity Dto 목적 데이터베이스와 상호작용, 비즈니스 로직 포함 데이터 전송 및 계층 간 데이터 교환 구성 DB 테이블과 직접 매핑, 필드에서 실제 데이터 포함 필요한 데이터만 포함, 간단한 구조 비즈니스 로직 포함 가능 (데이터베이스 관련 로직 포함) 포함하지 않음 (단순 데이터 구조) 사용 장소 데이터베이스 저장/조회 작업 서비스와 컨트롤러 간 데이터 전송 변경 주기 데이터베이스와 함께 변경 (영속성 연관) 데이터 전송 시 필요한 값만 포함
package com.example.orderserivce.vo;
import lombok.Data;
@Data
public class RequestOrder {
private String productId;
private Integer qty;
private Integer unitPrice;
}
package com.example.orderserivce.controller;
import com.example.orderserivce.dto.OrderDto;
import com.example.orderserivce.jpa.OrderEntity;
import com.example.orderserivce.jpa.OrderRepository;
import com.example.orderserivce.service.OrderService;
import com.example.orderserivce.vo.RequestOrder;
import com.example.orderserivce.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.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("order-service")
public class OrderController {
Environment env;
OrderService orderService;
@Autowired
public OrderController(Environment env, OrderService orderService, OrderRepository orderRepository) {
this.env = env;
this.orderService = orderService;
}
@GetMapping("/health_check")
public String healthCheck() {
return String.format("It's Working in Order Service on PORT %s", env.getProperty("local.server.port"));
}
@PostMapping("/{userId}/orders")
public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId, @RequestBody RequestOrder orderDetails){
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderDto orderDto = mapper.map(orderDetails, OrderDto.class);
orderDto.setUserId(userId);
OrderDto createdOrder = orderService.createOrder(orderDto);
ResponseOrder responseOrder = mapper.map(createdOrder, ResponseOrder.class);
return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder);
}
@GetMapping("/{userId}/orders")
public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId){
Iterable<OrderEntity> orderList = orderService.getAllOrdersByUserId(userId);
List<ResponseOrder> result = new ArrayList<>();
orderList.forEach(v -> {
result.add(new ModelMapper().map(v, ResponseOrder.class));
});
return ResponseEntity.status(HttpStatus.OK).body(result);
}
}
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
Eureka 등록 확인

사용자 등록

카탈로그 상품 조회

주문 서비스


➡ 사용자 아이디 13295d4a-eb42-41cb-9561-699484c4ceb0에 대하여 2건 주문 진행
주문 확인

DB 확인
