[인프런 워밍업 클럽 0기] BE 6일차 과제
9개월 전
문제 1
과제 #4에서 만들었던 API를 강의 내용처럼 Controller - Service - Repository로 분리해보세요!
Controller
@RestController
public class FruitController {
private final FruitService fruitService;
public FruitController(FruitService fruitService) {
this.fruitService = fruitService;
}
@PostMapping("/api/v1/fruit") // POST /api/v1/fruit
public void saveFruit(@RequestBody FruitCreateRequest request) {
fruitService.saveFruit(request);
}
@PutMapping("/api/v1/fruit")
public void updateFruit(@RequestBody FruitUpdateRequest request) {
fruitService.updateFruit(request);
}
@GetMapping("/api/v1/fruit/stat") // GET /api/v1/fruit/stat
public TotalPriceResponse getTotalPrice(@RequestBody TotalPriceRequest request) {
fruitService.getTotalPrice(request);
}
}
Service
public class FruitService {
private final FruitRepository fruitRepository;
public FruitService(JdbcTemplate jdbcTemplate) {
fruitRepository = new FruitRepository(jdbcTemplate);
}
public void updateFruit(FruitUpdateRequest request) {
if (fruitRepository.isFruitNotExist(request.getId())) {
throw new IllegalArgumentException();
}
fruitRepository.updateFruitId(request.getId());
}
public void saveFruit(FruitCreateRequest request) {
fruitRepository.saveFruit(request.getName(),request.getWarehousingDate(),request.getPrice());
}
public TotalPriceResponse getTotalPrice(TotalPriceRequest request) {
fruitRepository.getTotalPrice(request.getName());
}
}
Repository
public class FruitRepository {
private final JdbcTemplate jdbcTemplate;
public FruitRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public boolean isFruitNotExist(long id) {
String readSql = "SELECT id from fruit WHERE id = ?";
return jdbcTemplate.query(readSql, (rs, rowNum) -> 0, id).isEmpty();
}
public void updateFruitId(long id) {
String sql = "UPDATE fruit SET is_sold = TRUE WHERE id = ?";
jdbcTemplate.update(sql, id);
}
public void saveFruit(String name, LocalDate warehousingDate, long price) {
String sql = "INSERT INTO fruit (name, warehousingDate, price) VALUES (?, ?, ?)";
jdbcTemplate.update(sql, name, warehousingDate, price);
}
public TotalPriceResponse getTotalPrice(String name) {
String tSql = "SELECT SUM(price) FROM fruit WHERE name = ? AND is_sold = true";
String fSql = "SELECT SUM(price) FROM fruit WHERE name = ? AND is_sold = false";
long salesAmount = jdbcTemplate.queryForObject(tSql, long.class, name);
long notSalesAmount = jdbcTemplate.queryForObject(fSql, long.class, name);
return new TotalPriceResponse(salesAmount, notSalesAmount);
}
}
실행 결과
나머지 API들은 모두 정상 동작하지만, getTotalPrice는 repository에서 controller로 값이 전달되지 않는 현상이 발생했다.
두 SQL문을 받아 객체를 생성하여 반환하던 방식이
함수를 통해 jdbc를 전달하던 걸 생성자로 바꿔서 문제가 생긴건지
스프링과 어노테이션의 작동방식에서 인식을 못하는 건지
반환 방식을 지정해주면서 void가 아닌 경우 처리할 것들이 더 필요한 건지
아니면 여러 개가 섞여서 그런건지
아는 바가 없어 분리에는 성공했지만, 실행에는 1 실패를 기록하였다...
문제 2
문제 1에서 코드가 분리되면 FruitController
/ FruitService
/ FruitRepository
가 생겼을 것입니 다.
기존에 작성했던 FruitRepository
를 FruitMemoryRepository
와 FruitMySqlRepository
로 나누고 @Primary 어노테이션을 활용해 두 Repository를 바꿔가며 동작시킬 수 있도록 코드를 변경해보세요!
FruitRepository
public interface FruitRepository {
boolean isFruitNotExist(long id);
void updateFruitId(long id);
void saveFruit(String name, LocalDate warehousingDate, long price);
TotalPriceResponse getTotalPrice(String name);
}
FruitMySqlRepository(FruitMemoryRepository)
@Primary // 쓸 곳에만 작성!
@Repository
public class FruitMySqlRepository implements FruitRepository {
...
}
댓글을 작성해보세요.