우리는 스프링 컨테이너의 개념을 배우고, 기존에 작성했던 Controller 코드를 3단 분리해보았습니다. 앞으로 API를 개발할 때는 이 계층에 맞게 각 코드가 작성되어야 합니다! 🙂

과제 #4 에서 만들었던 API를 분리해보며, Controller - Service - Repository 계층에 익숙해져 봅시다! 👍

문제 1

과제 #4에서 만들었던 API를 강의 내용처럼 Controller - Service - Repository로 분리해보자.

결과 및 코드

과일 정보 저장 API

// Controller
@PostMapping("/fruit")
public void saveFruit(@RequestBody FruitCreateRequest request) {
	fruitService.saveFruit(request);
}

// Service
public void saveFruit(FruitCreateRequest request) {
	fruitRepository.saveFruit(
		request.getName(), request.getPrice(), request.getWarehousingDate()
	);
}

// Repository
public void saveFruit(String name, Long price, LocalDate warehousingDate) {
	String sql = "INSERT INTO fruit(name, price, warehousing_date) VALUES(?,?,?)";
	jdbcTemplate.update(sql, name, price, warehousingDate);
}

과일 정보 조회 API

// Controller
@GetMapping("/fruit")
public List<FruitResponse> getFruits() {
	return fruitService.getFruits();
}

// Service
public List<FruitResponse> getFruits() {
	return fruitRepository.getFruits();
}

// Repository
public List<FruitResponse> getFruits() {
	String sql = "SELECT * FROM fruit";
  return jdbcTemplate.query(sql, (rs, rowNum) -> {
      long id = rs.getLong("id");
      String name = rs.getString("name");
      long price = rs.getLong("price");
      LocalDate warehousingDate = rs.getDate("warehousing_date").toLocalDate();
      boolean isSold = rs.getBoolean("is_sold");
      return new FruitResponse(id, name, price, warehousingDate, isSold);
  });
}

과일 판매 API

// Controller
@PutMapping("/fruit")
public void sellFruit(@RequestBody FruitSellRequest request) {
	fruitService.sellFruit(request);
}

// Service
public void sellFruit(FruitSellRequest request) {
	if (fruitRepository.isFruitNotExist(request.getId())) {
		throw new IllegalArgumentException();
	}
  fruitRepository.updateFruitToSold(request.getId());
}

// Repository
public void updateFruitToSold(long id) {
  String sql = "UPDATE fruit SET is_sold = true WHERE id = ?";
  jdbcTemplate.update(sql, id);
}

과일 금액 조회 API

// Controller
@GetMapping("/fruit/stat")
public FruitStatResponse statFruit(@RequestParam String name) {
    return fruitService.statFruit(name);
}

// Service
public FruitStatResponse statFruit(String name) {
  long salesAmount = fruitRepository.getSalesAmount(name);
  long notSalesAmount = fruitRepository.getNotSalesAmount(name);
  return new FruitStatResponse(salesAmount, notSalesAmount);
}

// Repository
public long getSalesAmount(String name) {
  String salesSql = "SELECT SUM(price) FROM fruit WHERE name = ?" +
          "GROUP BY is_sold HAVING is_sold = true";
  return jdbcTemplate.query(salesSql, (rs, rowNum) ->
          rs.getLong("SUM(price)"), name).get(0);
}

public long getNotSalesAmount(String name) {
  String notSaleSql = "SELECT SUM(price) FROM fruit WHERE name = ?" +
          "GROUP BY is_sold HAVING is_sold = false";
  return jdbcTemplate.query(notSaleSql, (rs, rowNum) ->
          rs.getLong("SUM(price)"), name).get(0);
}

문제 2