🖤인프런만의 100% 블프 이벤트🖤

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

문제 1

과제 #4에서 만들었던 API를 Controller - Service - Repository로 분리하기

4일차 과제 내용: https://www.inflearn.com/blogs/6676

Controller

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

    private final FruitService fruitService;


    @PostMapping
    public ResponseEntity<?> savedFruit(@RequestBody FruitRequest request) {
        fruitService.save(request);
        return ResponseEntity.ok().build();
    }

    @PutMapping
    public ResponseEntity<?> FruitStateUpdate(@RequestBody FruitRequest request) {
        fruitService.stateUpdate(request);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/stat")
    public ResponseEntity<?> isSaleStateTotalPrice(@RequestParam String name) {
        return ResponseEntity.ok(fruitService.getSum(name));
    }
}

Service

@RequiredArgsConstructor
@Service
public class FruitService {

    private final FruitRepository fruitRepository;

    public void save(FruitRequest request) {
        fruitRepository.saveFruit(request);
    }

    public void stateUpdate(FruitRequest request) {

        boolean isFruitNotExist = fruitRepository.isFruitNotExist(request.getId());
        if (isFruitNotExist) {
            throw new IllegalStateException("일치하는 과일 정보가 없습니다.");
        }
        fruitRepository.updateFruit(request.getId());
    }

    public FruitTotalPriceResponse getSum(String name) {
        boolean isFruitNotExist = fruitRepository.isFruitNotExist(name);
        if (isFruitNotExist) {
            throw new IllegalStateException("일치하는 과일 정보가 없습니다.");
        }


        List<FruitTotalPriceResponse> sumResult = fruitRepository.getSum(name);

        long salesAmount = 0;
        long noSalesAmount = 0;
        for (FruitTotalPriceResponse result : sumResult) {
            salesAmount += result.getSalesAmount();
            noSalesAmount += result.getNoSalesAmount();
        }
        return new FruitTotalPriceResponse(salesAmount, noSalesAmount);
    }
}

 

Repository

 

@RequiredArgsConstructor
@Repository
public class FruitRepository {

    private final JdbcTemplate jdbcTemplate;

    public void saveFruit(FruitRequest request) {
        String sql = "insert into fruit (name, warehousingDate, price) values (?, ? ,?)";
        jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice());
    }

    public void updateFruit(long id) {
        String sql = "update fruit set is_sale = 1 where id = ?";
        jdbcTemplate.update(sql, id);
    }

    public List<FruitTotalPriceResponse> getSum(String name) {
        String sql = "select is_sale, sum(price) as totalPrice from fruit " +
                "where name = ? group by is_sale";
        return jdbcTemplate.query(sql, new Object[]{name},
                (rs, rowNum) -> new FruitTotalPriceResponse(
                        rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0,
                        !rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0));
    }

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

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

 

문제 2

 

FruitRepository를 FruitMemoryRepository 와 FruitMemoryRepository 로 나누자

 

먼저 FruitRepository를 만든다

public interface FruitRepository {

    public void saveFruit(FruitRequest request);
    public void updateFruit(long id);
    public List<FruitTotalPriceResponse> getSum(String name);
    public boolean isFruitNotExist(long id);
    public boolean isFruitNotExist(String name);
}

FruitMemoryRepository

@Primary
@Repository
public class FruitMemoryRepository implements FruitRepository{
    private final List<FruitRequest> fruits = new ArrayList<>();

    @Override
    public void saveFruit(FruitRequest request) {
        fruits.add(request);
    }

    @Override
    public void updateFruit(long id) {
        fruits.stream()
                .filter(fruit -> fruit.getId() == id)
                .findFirst()
                .ifPresent(fruit -> fruit.setSale(true));
    }

    @Override
    public List<FruitTotalPriceResponse> getSum(String name) {
        return fruits.stream()
                .filter(fruit -> fruit.getName().equals(name))
                .collect(Collectors.groupingBy(FruitRequest::isSale,
                        Collectors.summingLong(FruitRequest::getPrice)))
                .entrySet().stream()
                .map(entry -> new FruitTotalPriceResponse(
                        entry.getKey() ? entry.getValue() : 0,
                        !entry.getKey() ? entry.getValue() : 0))
                .collect(Collectors.toList());
    }

    @Override
    public boolean isFruitNotExist(long id) {
        return fruits.stream().noneMatch(fruit -> fruit.getId() == id);
    }

    @Override
    public boolean isFruitNotExist(String name) {
        return fruits.stream().noneMatch(fruit -> fruit.getName().equals(name));
    }
}

 

FruitMySqlRepository

@Qualifier("mysql")
@RequiredArgsConstructor
@Repository
public class FruitMySqlRepository implements FruitRepository {

    private final JdbcTemplate jdbcTemplate;

    public void saveFruit(FruitRequest request) {
        String sql = "insert into fruit (name, warehousingDate, price) values (?, ? ,?)";
        jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice());
    }

    public void updateFruit(long id) {
        String sql = "update fruit set is_sale = 1 where id = ?";
        jdbcTemplate.update(sql, id);
    }

    public List<FruitTotalPriceResponse> getSum(String name) {
        String sql = "select is_sale, sum(price) as totalPrice from fruit " +
                "where name = ? group by is_sale";
        return jdbcTemplate.query(sql, new Object[]{name},
                (rs, rowNum) -> new FruitTotalPriceResponse(
                        rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0,
                        !rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0));
    }

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

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

 

FruitService 부분에 생성자에 @Qualifier("mysql")가 있기 때문에 FruitMemoryRepository에 @Primary 어노테이션이 있더라도 직접 지정한 클래스가 우선순위가 높기 때문에 FruitMemoryRepository 주입 받는다.

 

public FruitService(@Qualifier("mysql")FruitRepository fruitRepository) {
    this.fruitRepository = fruitRepository;
}

댓글을 작성해보세요.

채널톡 아이콘