본문 바로가기
Develop/Feature

Layered Architecture 구조, API 적용하기

by 코젼 2024. 5. 28.
728x90
반응형

Controller - Service - Repository 구조를 사용한다.

 

API 기능 명세

간단하게 명세해두었다.

  • POST: 과일 정보 저장
  • PUT: 팔린 과일의 정보를 flag로 기록
  • GET: 팔린 금액, 팔리지 않은 금액 조회

SQL

create table fruit
(
    id              bigint auto_increment,
    name            varchar(20) comment '과일명',
    warehousingDate varchar(50) comment '등록 날짜',
    price           bigint comment '가격',
    sell            tinyint default 0 comment '판매 여부',
    primary key (id)
);

 

Layered Architecture 구조

Controller

package com.group.libraryapp.report.sec02;

import com.group.libraryapp.report.sec02.dto.FruitDto;
import com.group.libraryapp.report.sec02.dto.ResponseAmount;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
public class FruitController {

    private final FruitService service;

    public FruitController(FruitService service) {
        this.service = service;
    }

    //과일 정보 저장
    @PostMapping("/api/v1/fruit")
    public void save(@RequestBody FruitDto fruit) {
        service.save(fruit);
    }

    //팔린 과일 정보 기록
    @PutMapping("/api/v1/fruit")
    public void record(@RequestBody FruitDto fruit) {
        service.sellRecord(fruit);
    }

    //팔린 금액, 팔리지 않은 금액 조회
    @GetMapping("/api/v1/fruit/stat")
    public ResponseAmount sellingAmount(@RequestParam String name) {
        return service.searchAmount(name);
    }
}

 

Service

package com.group.libraryapp.report.sec02;

import com.group.libraryapp.report.sec02.dto.FruitDto;
import com.group.libraryapp.report.sec02.dto.ResponseAmount;
import com.group.libraryapp.report.sec02.repository.FruitRepository;
import org.springframework.stereotype.Service;

@Service
public class FruitService {

    private final FruitRepository repository;

    public FruitService(FruitRepository repository) {
        this.repository = repository;
    }


    public void save(FruitDto fruit) {
        repository.save(fruit.getName(), fruit.getWarehousingDate(), fruit.getPrice());
    }

    public void sellRecord(FruitDto fruit) {
        repository.sellRecord(fruit.getId());
    }

    public ResponseAmount searchAmount(String name) {
        return repository.searchAmount(name);
    }
}

 

Repository

package com.group.libraryapp.report.sec02.repository;

import com.group.libraryapp.report.sec02.dto.ResponseAmount;

public interface FruitRepository {
    void save(String name, String warehousingDate, int price);
    void sellRecord(Long id);
    ResponseAmount searchAmount(String name);
}
package com.group.libraryapp.report.sec02.repository;

import com.group.libraryapp.report.sec02.dto.ResponseAmount;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Primary
@Repository
public class FruitMemoryRepository implements FruitRepository{

    private final JdbcTemplate jdbcTemplate;

    public FruitMemoryRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void save(String name, String warehousingDate, int price) {
        String sql = "insert into fruit (name, warehousingDate, price) values (?, ?, ?)";
        jdbcTemplate.update(sql, name, warehousingDate, price);
    }

    @Override
    public void sellRecord(Long id) {
        String sql = "update fruit set sell = 1 where id = ?";
        jdbcTemplate.update(sql, id);
    }

    @Override
    public ResponseAmount searchAmount(String name) {
        ResponseAmount amount = new ResponseAmount();

        String sales = "select sell, sum(price) as sum_price from fruit where name = ? group by sell";
        jdbcTemplate.query(sales, (rs, rowNum) -> {
            boolean sell = rs.getBoolean("sell");
            if (sell) {
                amount.setSalesAmount(rs.getLong("sum_price"));
            } else {
                amount.setNotSalesAmount(rs.getLong("sum_price"));
            }
            return amount;
        }, name);

        return amount;
    }
}
728x90
반응형

'Develop > Feature' 카테고리의 다른 글

[Docker] Database docker-compose 구축(mysql, redis)  (0) 2024.07.22
Filter, Interceptor  (0) 2024.07.16
Mac Node.js 설치  (0) 2024.06.24
Swagger UI 사용  (0) 2024.06.12
Apache 아파치 http 서버 설치  (0) 2024.03.22

댓글