[인프런 워밍업 클럽 BE 0기] 6일차 과제

[인프런 워밍업 클럽 BE 0기] 6일차 과제

문제 1

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


  • Controller code

@RequestMapping("/api/v1/fruit")
@RestController
public class FruitController {

    private final FruitService fruitService;

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

    @PostMapping()
    public void addFruit(@RequestBody FruitInfRequest request) {
        fruitService.addFruit(request);
    }

    @PutMapping()
    public void isSoldFruit(@RequestBody FruitSoldRequest request) {
        fruitService.isSoldFruit(request);
    }

    @GetMapping("/stat")
    public FruitAmountResponse checkSalesAmount(@RequestParam String name) {
        return fruitService.checkSalesAmount(name);
    }
}
  • Service code

@Service
public class FruitService {

    private final FruitRepository fruitRepository;

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

    public void addFruit(FruitInfRequest request){
        fruitRepository.addFruit(request);
    }

    public void isSoldFruit(FruitSoldRequest request) {
        fruitRepository.isSoldFruit(request);
    }

    public FruitAmountResponse checkSalesAmount(String name) {
        return fruitRepository.checkSalesAmount(name);
    }
}
  • Repository code

@Repository
public class FruitRepository {

    private final JdbcTemplate jdbcTemplate;

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

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

    public void isSoldFruit(FruitSoldRequest request) {
        String readSql = "SELECT * FROM fruit WHERE id = ? and is_sold = false";
        boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
        if (isFruitNotExist) {
            throw new IllegalArgumentException();
        }
        String sql = "UPDATE fruit SET is_sold = true WHERE id = ?";
        jdbcTemplate.update(sql, request.getId());
    }

    public FruitAmountResponse checkSalesAmount(String name) {
        String readSql = "SELECT * FROM fruit WHERE name = ?";
        boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, name).isEmpty();
        if (isFruitNotExist) {
            throw new IllegalArgumentException();
        }

        String soldSql = "SELECT sum(price) FROM fruit WHERE is_sold = true GROUP BY name having name = ?";
        String notSoldSql = "SELECT sum(price) FROM fruit WHERE is_sold = false GROUP BY name having name  = ?";

        long salesAmount = jdbcTemplate.queryForObject(soldSql, long.class, name);
        long notSalesAmount = jdbcTemplate.queryForObject(notSoldSql, long.class, name);

        return new FruitAmountResponse(salesAmount, notSalesAmount);
    }
}

문제 2

문제 1에서 코드가 분리되면 FruitController/ FruitService / FruitRepository가 생겼을 것 입니다.

기존에 작성했던 FruitRepositoryFruitMemoryRepositoryFruitMySqlRepository로 나누고 @Primary어노테이션을 활용해 두 Repository를 바꿔가며 동작시킬 수 있도록 코드를 변경해보세요


  • FruitService

private final FruitRepository fruitRepository;

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

public interface FruitRepository {

    void addFruit(FruitInfRequest request);

    void isSoldFruit(FruitSoldRequest request);

    FruitAmountResponse checkSalesAmount(String name);
}
  • FruitMysqlRepository

@Repository
@Primary // 사용할 Reposiroty에 추가
public class FruitMysqlRepository implements FruitRepository{

    private final JdbcTemplate jdbcTemplate;

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

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

    @Override
    public void isSoldFruit(FruitSoldRequest request) {
        String readSql = "SELECT * FROM fruit WHERE id = ? and is_sold = false";
        boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
        if (isFruitNotExist) {
            throw new IllegalArgumentException();
        }
        String sql = "UPDATE fruit SET is_sold = true WHERE id = ?";
        jdbcTemplate.update(sql, request.getId());
    }

    @Override
    public FruitAmountResponse checkSalesAmount(String name) {
        String readSql = "SELECT * FROM fruit WHERE name = ?";
        boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, name).isEmpty();
        if (isFruitNotExist) {
            throw new IllegalArgumentException();
        }

        String soldSql = "SELECT sum(price) FROM fruit WHERE is_sold = true GROUP BY name having name = ?";
        String notSoldSql = "SELECT sum(price) FROM fruit WHERE is_sold = false GROUP BY name having name  = ?";

        long salesAmount = jdbcTemplate.queryForObject(soldSql, long.class, name);
        long notSalesAmount = jdbcTemplate.queryForObject(notSoldSql, long.class, name);

        return new FruitAmountResponse(salesAmount, notSalesAmount);
    }
}

@Primary 어노테이션을 통해 FruitService에서 받는 Repository가 어노테이션을 가진 FruitMysqlRepository가 되도록 함.

댓글을 작성해보세요.

채널톡 아이콘