3 분 소요

image

[인프런 워밍업 클럽 1기] BE 6일차 본 게시글은 다음 강의 내용을 진행하고 있습니다.

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지] - https://inf.run/XKQg

imageFruitController.java

@RestController
public class FruitController {

    private final JdbcTemplate jdbcTemplate;

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

    @PostMapping("/api/v1/fruit")
    public void saveFruit(@RequestBody FruitRequest request) {
        String sql = "INSERT INTO fruit (name, warehousingDate, price) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice());
    }

    @PutMapping("/api/v1/fruit")
    public void updateFruit(@RequestBody SoldRequest request) {
        String readSql = "SELECT * FROM fruit WHERE id = ?";

        boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
        if (isFruitNotExist) {
            throw new IllegalArgumentException();
        }

        String updateSql = "UPDATE fruit SET status  = true WHERE id = ?";
        jdbcTemplate.update(updateSql, request.getId());
    }

    @GetMapping("/api/v1/fruit/stat")
    public SalesSumResponse statFruit(@RequestParam String name) {

        String salesSql = "SELECT sum(price) FROM fruit WHERE status = true GROUP BY name HAVING name = ?";
        String notSalesSql = "SELECT sum(price) FROM fruit WHERE status = false GROUP BY name HAVING name = ?";


        long salesAmount = jdbcTemplate.queryForObject(salesSql, long.class, name);
        long notSalesAmount = jdbcTemplate.queryForObject(notSalesSql, long.class, name);


        return new SalesSumResponse(salesAmount, notSalesAmount);
    }
}

Controller-Service-Repository 구조로 리팩토링

FruitController.java

 @RestController
public class FruitController {
    private final FruitService fruitService;

    @Autowired
    public FruitController(FruitService fruitService) {
        this.fruitService = fruitService;
    }

    @PostMapping("/api/v1/fruit")
    public void addFruit(@RequestBody Fruit fruit) {
        fruitService.addFruit(fruit);
    }

    @PutMapping("/api/v1/fruit")
    public void updateFruit(@RequestBody Fruit fruit) {
        fruitService.updateFruit(fruit);
    }

    @GetMapping("/api/v1/fruit/stat")
    public FruitSalesData getFruitStats(@RequestParam String name) {
        return fruitService.getFruitSales(name);
    }
}

FruitService.java

@Service
public class FruitService {
    private final FruitRepository fruitRepository;

    @Autowired
    public FruitService(FruitRepository fruitRepository) {
        this.fruitRepository = fruitRepository;
    }

    public void addFruit(Fruit fruit){
        fruitRepository.save(fruit);
    }

    public void updateFruit(Fruit fruit){
        fruitRepository.update(fruit);
    }

    public FruitSalesData getFruitSales(String name) {
        return fruitRepository.getFruitSalesData(name);
    }
}

FruitRepository.java

@Repository
public class FruitRepository {

    private final JdbcTemplate jdbcTemplate;

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

    public void save(Fruit fruit) {
        String sql = "INSERT INTO Fruits(name, warehousingDate, price) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, fruit.getName(), fruit.getWarehousingDate(), fruit.getPrice());
    }

    public void update(Fruit fruit) {
        String sql = "UPDATE Fruits SET status = false WHERE id = ?";
        jdbcTemplate.update(sql, fruit.getId());
    }

    public FruitSalesData getFruitSalesData(String name) {
        String salesAmountSql = "SELECT COALESCE(SUM(price), 0) FROM Fruits WHERE name = ? AND status = true";
        Long salesAmount = jdbcTemplate.queryForObject(salesAmountSql, new Object[]{name}, Long.class);

        String notSalesAmountSql = "SELECT COALESCE(SUM(price), 0) FROM Fruits WHERE name = ? AND status = false";
        Long notSalesAmount = jdbcTemplate.queryForObject(notSalesAmountSql, new Object[]{name}, Long.class);

        return new FruitSalesData(salesAmount, notSalesAmount);
    }
}

imageFruitRepository.java

public interface FruitRepository {
    void save(Fruit fruit);
    void update(Fruit fruit);

    FruitSalesData getFruitSalesData(String name);
}

FruitMemoryRepository.java

@Repository
public class FruitMemoryRepository implements FruitRepository {
    private final List<Fruit> fruits; // 가정: 모든 과일 데이터가 이미 메모리에 로드되어 있다고 가정

    @Autowired
    public FruitMySqlRepository(List<Fruit> fruits) {
        this.fruits = fruits;
    }

    @Override
    public void save(Fruit fruit) {
        fruits.add(fruit);
    }

    @Override
    public void update(Fruit fruit) {
        // id로 과일을 찾아 상태를 변경
        fruits.stream()
              .filter(f -> f.getId() == fruit.getId())
              .findFirst()
              .ifPresent(f -> f.setStatus(false));
    }

    @Override
    public FruitSalesData getFruitSalesData(String name) {
        // 주어진 이름의 과일에 대한 판매 및 비판매 금액 계산
        Long salesAmount = fruits.stream()
                                 .filter(f -> f.getName().equals(name) && f.isStatus())
                                 .mapToLong(Fruit::getPrice)
                                 .sum();

        Long notSalesAmount = fruits.stream()
                                    .filter(f -> f.getName().equals(name) && !f.isStatus())
                                    .mapToLong(Fruit::getPrice)
                                    .sum();

        return new FruitSalesData(salesAmount, notSalesAmount);
    }
}

FruitMySqlRepository.java

@Repository
@Primary
public class FruitMySqlRepository implements FruitRepository {
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public FruitMySqlRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void save(Fruit fruit) {
        String sql = "INSERT INTO Fruits(name, warehousingDate, price) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, fruit.getName(), fruit.getWarehousingDate(), fruit.getPrice());
    }

    @Override
    public void update(Fruit fruit) {
        String sql = "UPDATE Fruits SET status = false WHERE id = ?";
        jdbcTemplate.update(sql, fruit.getId());
    }

    @Override
    public FruitSalesData getFruitSalesData(String name) {
        String salesAmountSql = "SELECT COALESCE(SUM(price), 0) FROM Fruits WHERE name = ? AND status = true";
        Long salesAmount = jdbcTemplate.queryForObject(salesAmountSql, new Object[]{name}, Long.class);

        String notSalesAmountSql = "SELECT COALESCE(SUM(price), 0) FROM Fruits WHERE name = ? AND status = false";
        Long notSalesAmount = jdbcTemplate.queryForObject(notSalesAmountSql, new Object[]{name}, Long.class);

        return new FruitSalesData(salesAmount, notSalesAmount);
    }
}

댓글남기기