워밍업 클럽 - 백엔드 6일차 과제

워밍업 클럽 - 백엔드 6일차 과제

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! 강의 6일차 과제입니다.

(강의 링크)

이번 과제는 기존의 4일차 과제에서 만든 코드를 서비스, 컨트롤러, 리포지토리로 레이어 나누기이다.

문제 1. 서비스, 컨트롤러, 리포지토리로 레이어 분리

Request를 받고 전달하는 역할만하도록 먼저 FruitController의 모든 비지니스 로직은 서비스로 옮겼다.

FruitController.java

@RestController
@RequestMapping("/api/v1/fruit")
public class FruitController {
    private final FruitService fruitService;

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

    @PostMapping("")
    public FruitCreateResponse createFruit(@RequestBody FruitCreateRequest request) {
        return fruitService.CreateFruit(request);
    }

    @PutMapping("")
    public FruitSellResponse sellFruit(@RequestBody FruitSellRequest request) {
        return fruitService.sellFruit(request);
    }

    @GetMapping("/stat")
    public FruitStatResponse getFruitStat(FruitStatRequest request) {
        return fruitService.getFruitStat(request);
    }
}

다음 서비스에 있는 모든 저장소 관련 코드들을 Repository로 옮겼다.

이때 필요한 인터페이스를 FruitRepository.java에 정의했다.

public interface FruitRepository {
    Fruit createFruit(String name, LocalDate warehousingDate, Long price, boolean isSold);
    void updateFruit(Long id);
    List<Fruit> getFruits(String name);
}

FruitMySqlRepository는 다음과 같다.

@Primary
@Repository
public class FruitMySqlRepository implements FruitRepository {
    private final JdbcTemplate jdbcTemplate;

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

    @Override
    public Fruit createFruit(String name, LocalDate warehousingDate, Long price, boolean isSold) {
        String sql = "INSERT INTO fruit (name, warehousing_date, price) VALUES (?, ?, ?)";
        Fruit fruit = new Fruit(name, warehousingDate, price, false);
        jdbcTemplate.update(sql, fruit.getName(), fruit.getWarehousingDate(), fruit.getPrice());
        return fruit;
    }

    @Override
    public void updateFruit(Long id) {
        String sql = "UPDATE fruit SET is_sold = true WHERE id = ?";
        jdbcTemplate.update(sql, id);
    }

    @Override
    public List<Fruit> getFruits(String name) {
        String sql = "SELECT name, warehousing_date, price, is_sold FROM fruit WHERE name = ?";
        return jdbcTemplate.query(sql, (rs, rowNum) -> new Fruit(
                rs.getString("name"),
                rs.getDate("warehousing_date").toLocalDate(),
                rs.getLong("price"),
                rs.getBoolean("is_sold")
        ), name);
    }
}

 

문제 2. 두 가지의 레포지토리를 만들어서 외부에서 어떤 것을 주입할지 변경해보기

똑같이 FruitRepository를 구현하는 FruitMemoryRepository를 만든다.

FruitMemoryRepository.java

@Repository
public class FruitMemoryRepository implements FruitRepository {
    private final List<Fruit> fruits;
    private static Long id = 1L;

    public FruitMemoryRepository() {
        fruits = new ArrayList<>();
    }

    @Override
    public Fruit createFruit(String name, LocalDate warehousingDate, Long price, boolean isSold) {
        Fruit fruit = new Fruit(id++, name, warehousingDate, price, isSold);
        fruits.add(fruit);
        return fruit;
    }

    @Override
    public void updateFruit(Long id) {
        for (Fruit fruit : fruits) {
            if (fruit.getId().equals(id)) {
                fruit.setSold(true);
                break;
            }
        }
    }

    @Override
    public List<Fruit> getFruits(String name) {
        List<Fruit> result = new ArrayList<>();
        for (Fruit fruit : fruits) {
            if (fruit.getName().equals(name)) {
                result.add(fruit);
            }
        }
        return result;
    }
}

 그리고 마지막으로 @Primary 어노테이션을 이 클래스로 옮겨 달아주면 FruitService에게 이 저장소를 주입해주게 된다.

댓글을 작성해보세요.

채널톡 아이콘