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

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

image4일차 (https://www.inflearn.com/blogs/6687)에서 이미 애플리케이션을 계층별로 나눠서 개발했기에 여기선 복습하는 느낌으로 정리하겠습니다.

 

[컨트롤러]

@RestController
public class FruitController {
    private final FruitService fruitService;

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

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

    @PutMapping("/api/v1/fruit")
    public void updateFruitStock(@RequestBody FruitStockUpdateRequest request) {
        fruitService.updateFruitStock(request);
    }

    @GetMapping("/api/v1/fruit/stat")
    public FruitSalesRecordResponse getFruitSalesRecord(@RequestParam(value="name") String name) {
        return fruitService.getFruitSalesRecord(name);
    }
}

 

[서비스]

@Service
public class FruitService {
    private final FruitRepository fruitRepository;

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

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


    public void updateFruitStock(FruitStockUpdateRequest request) {
        if (fruitRepository.isFruitEmpty(request.getId())) {
            throw new IllegalStateException("등록되지 않은 과일입니다.");
        }

        fruitRepository.updateStock(request.getId());
    }

    public void getFruitSalesRecord(String name) {
        if (fruitRepository.isFruitEmpty(name)) {
            throw new IllegalStateException("등록되지 않은 과일입니다.");
        }

        return fruitRepository.getSalesRecord(name);
    }
}

 

[레포지토리]

public interface FruitRepository {

    void save(String name, LocalDate warehousingDate, Long price);

    void updateStock(Long id);

    FruitSalesRecordResponse getSalesRecord(String name);

    boolean isFruitEmpty(Long id);

    boolean isFruitEmpty(String name);
}
@Repository
public class FruitMySqlRepository implements FruitRepository {
    private final JdbcTemplate jdbcTemplate;

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

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

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

    @Override
    public FruitSalesRecordResponse getSalesRecord(String name) {
        String sql = "select is_sold, sum(price) as total_price from fruit where name = ? group by is_sold";
        FruitSalesRecordResponse response = new FruitSalesRecordResponse();

        jdbcTemplate.query(sql, (rs, rowNum) -> {
            if (rs.getBoolean("is_sold")) {
                response.setSalesAmount(rs.getLong("total_price"));
            } else {
                response.setNotSalesAmount(rs.getLong("total_price"));
            }
            return 0;
        });

        return response;
    }

    @Override
    public boolean isFruitEmpty(Long id) {
        String sql = "select * from fruit where id = ?";
        return jdbcTemplate.query(sql, (rs, rowNum) -> 0, id).isEmpty();
    }

    @Override
    public boolean isFruitEmpty(String name) {
        String sql = "select * from fruit where name = ?";
        return jdbcTemplate.query(sql, (rs, rowNum) -> 0, name).isEmpty();
    }
}

 

image

@Repository
public class FruitMemoryRepository implements FruitRepository {

    @Override
    public void save(String name, LocalDate warehousingDate, Long price) {
    }

    @Override
    public FruitSalesRecordResponse getSalesRecord(String name) {
        return null;
    }

    @Override
    public void updateStock(Long id) {
    }

    @Override
    public boolean isFruitEmpty(Long id) {
        return false;
    }

    @Override
    public boolean isFruitEmpty(String name) {
        return false;
    }
}

image메모리 DB를 이용하는 레포지토리를 추가로 생성하고 @Repository를 선언했습니다. 이 상태에서 애플리케이션을 시행하면 에러가 발생합니다. 서비스의 fruitRepository 필드에는 fruitMySqlRepository 빈과 fruitMemoryRepository 빈 모두 들어갈 수 있다 보니 스프링 부트가 결정을 내리지 못하기 때문입니다.

 

@Repository
@Primary
public class FruitMySqlRepository implements FruitRepository {
    // 생략
}

이럴 땐 @Primary를 선언해 본인이 사용할 레포지토리한테 등록 우선권을 주면 됩니다.

댓글을 작성해보세요.