Nellie's Blog

[TIL-230220월] 백준 알고리즘, 개인 프로젝트 MSA로 본문

회고록

[TIL-230220월] 백준 알고리즘, 개인 프로젝트 MSA로

Nellie Kim 2023. 2. 21. 01:13
728x90

배운점

1. 알고리즘 공부

백준 기초 알고리즘 6문제 풀고, 인강을 2시간정도 들었다. 그리디와 구현에 대한 강의였다. 숙달이 필요할 것 같다.

 

2. 개인프로젝트 매출관련 서버 MSA처리

개인 붕어빵 프로젝트에 sales 프로젝트를 따로 하나 만들었다. 

 

매출은 메인프로젝트에서 처리하지 않고, 다른 서버(8081)에서 처리하도록 하는 것이 MSA(MicroService Architecture)이다. 각각의 서비스를 모듈화 시키는 것이다.

기본페이지에서 판매 및 가게등록 등 기본적인 서비스를 진행하고,  매출페이지를 따로 서버를 띄워(sales 프로젝트, 8081서버)에서 처리하는 것이다. 기본서버에서 매출서버를 API로 호출하는 형태이다. 

 

MSA의 장점

각각의 서비스는 모듈화가 되어있으며 이러한 모듈까리는 RPC 또는 message-driven API등을 이용하여 통신한다. 이러한 MSA는 각각 개별의 서비스 개발을 빠르게 하며, 유지보수도 쉽게할 수 있도록 한다. 

 

 

MSA의 특징

MSA는 API를 통해서만 상호작용할 수 있다. 즉, 마이크로 서비스는 서비스의 end-point(접근점)을 API 형태로 외부에 노출하고, 실질적인 세부 사항은 모두 추상화한다. 내부의 구현 로직, 아키텍처와 프로그래밍 언어, 데이터베이스, 품질 유지 체계와 같은 기술적인 사항들은 서비스 API에 의해 철저하게 가려진다. 

 

- application.properties

spring.datasource.password=1234
spring.datasource.username=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/WINTER_FOODIES?useUnicode=true&serverTimezone=UTC

mybatis.mapper-locations=classpath:/mybatis/mapper/*.xml

server.port=8081

 

- mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>

 

- Sales.java

package com.winterfoodies.dto;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@ToString
@Setter
public class Sales {
    private Long sales_id;
    private Long product_id;
    private Long customer_id;
    private Long store_id;
    private String order_at;
    private Long total_price;
}

 

- SalesMapper.java (인터페이스)

package com.winterfoodies.mapper;

import com.winterfoodies.dto.Sales;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@Mapper
public interface SalesMapper {
    List<Sales> getAllSalesByStoreId(Long storeId);

    void insertSales(Sales sales);

    Long getAllSalesByMonth(Long storeId);

    Long getAllSalesByYear(Long storeId);

    Long getYesterDaySales(Long storeId);

    Long getTotalOrdersCount(Long storeId);
}

 

- SalesMapper.xml (쿼리작성 - mybatis)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--해당 store_id의 salesDto목록을 모두 가져온다-->
<mapper namespace="com.winterfoodies.mapper.SalesMapper">
    <select id="getAllSalesByStoreId" parameterType="java.lang.Long" resultType="com.winterfoodies.dto.Sales">
        SELECT * FROM sales where sales.store_id = #{store_id}
    </select>

<!--salesDto에 값을 insert 한다-->
    <insert id="insertSales" parameterType="com.winterfoodies.dto.Sales">
        INSERT INTO sales(customer_id, store_id, total_price, product_id, order_at)
        VALUES (#{customer_id}, #{store_id}, #{total_price}, #{product_id}, #{order_at})  <!--물음표 아닌 prepared statement 로-->
    </insert>

<!--이 달의 매출-->

    <select id="getAllSalesByMonth" parameterType="java.lang.Long" resultType="com.winterfoodies.dto.Sales">
    <![CDATA[
        SELECT sum(total_price) FROM sales
        WHERE sales.store_id = #{store_id} AND (order_at > LAST_DAY(NOW() - interval 1 month)) AND order_at <= LAST_DAY(NOW())
        ]]>
    </select>


<!--올해의 매출-->
    <select id="getAllSalesByYear" parameterType="java.lang.Long" resultType="com.winterfoodies.dto.Sales">
        SELECT sum(total_price) FROM sales
        WHERE sales.store_id = #{store_id} AND year(order_at) = year(now())
    </select>

<!--어제의 매출-->
    <select id="getYesterDaySales" parameterType="java.lang.Long" resultType="com.winterfoodies.dto.Sales">
        SELECT sum(total_price) FROM sales
        WHERE sales.store_id = #{store_id} AND order_at = curdate() - INTERVAL 1 DAY
    </select>

<!--총 누적 주문건 수-->
    <select id="getTotalOrdersCount" parameterType="java.lang.Long" resultType="com.winterfoodies.dto.Sales">
        SELECT count(*) FROM sales
        WHERE sales.store_id = #{store_id}
    </select>
</mapper>

 

 

- SalesController.java

package com.winterfoodies.controller;


import com.winterfoodies.dto.Sales;
import com.winterfoodies.mapper.SalesMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/sales")
public class SalesController {

    private final SalesMapper salesMapper;

    // 매출 데이터 insert
    @PostMapping("/insert")
    public Integer insertSales(@RequestBody Sales sales){
        System.out.println("매출 데이터 인서트 요청이 들어왔습니다.");
        System.out.println(sales);
        try {
            salesMapper.insertSales(sales);
        }catch (Exception e){
            return 0;
        }
        return 1;
    }

    //전체 매출 데이터 조회
    @GetMapping("/getall/{storeId}")
    public List<Sales> getAllSalesByStoreId(@PathVariable Long storeId){
        System.out.println("매출 데이터 전체 요청이 들어왔습니다.");
        System.out.println(storeId);
        try {
            salesMapper.getAllSalesByStoreId(storeId);
        } catch (Exception e) {
            return null;
        }
        return null;
    }

    //이달의 매출
    @GetMapping("/monthsalesstoreid/{storeId}")
    public Long getAllSalesByMonth(@PathVariable Long storeId){
        System.out.println("이달의 매출 계산 요청이 들어왔습니다.");
        System.out.println(storeId);
        try {
            salesMapper.getAllSalesByMonth(storeId);
        } catch (Exception e) {
            return 0L;
        }
        return 1L;
    }

    // 올해의 매출
    @GetMapping("/yearsalesstoreid/{storeId}")
    public Long getAllSalesByYear(@PathVariable Long storeId){
        System.out.println("올해의 매출 계산 요청이 들어왔습니다.");
        System.out.println(storeId);
        try {
            salesMapper.getAllSalesByYear(storeId);
        } catch (Exception e) {
            return 0L;
        }
        return 1L;
    }

    // 어제의 매출
    @GetMapping("/yesterdaysalesstoreid/{storeId}")
    public Long getYesterDaySales(@PathVariable Long storeId){
        System.out.println("어제의 매출 계산 요청이 들어왔습니다.");
        System.out.println(storeId);
        try {
            salesMapper.getYesterDaySales(storeId);
        } catch (Exception e) {
            return 0L;
        }
        return 1L;
    }

    // 총 누적 주문건수
    @GetMapping("/totalsalesstoreid/{storeId}")
    public Long getTotalOrdersCount(@PathVariable Long storeId){
        System.out.println("총 누적 주문건수 요청이 들어왔습니다.");
        System.out.println(storeId);
        try {
            salesMapper.getTotalOrdersCount(storeId);
        } catch (Exception e) {
            return 0L;
        }
        return 1L;
    }

}

 

 

느낀점

정처기에서 배웠던 MSA를 프로젝트에 실제로 적용해보니 신기했다. 조금 더 깔끔하고 멋진 코드가 된 것 같아서 기분이 좋다. 더 공부해서 더 멋진 코드를 만들고 싶다.