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

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

문제 1

과제 #6에서 만들었던 Fruit 기능들을 JPA를 이용하도록 변경해보세요

  • Fruit

@Entity
public class Fruit {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = null;

    @Column(nullable = false, length = 20, name = "name")
    private String name;
    private Integer price;
    private boolean isSold;
    private LocalDate warehousingDate;

    protected Fruit() {}

    public Fruit(String name, Integer price,
                 boolean isSold, LocalDate warehousingDate) {
        if(name == null || name.isBlank()) {
            throw new IllegalArgumentException(String.format("name(%s)은 존재하지 않습니다.
                                                                 다시 입력해주세요.", name));
        }
        this.name = name;
        this.price = price;
        this.isSold = isSold;
        this.warehousingDate = warehousingDate;
    }

    public void updateName(String name) {
        this.name = name;
    }
}
  •  FruitRepository

public interface FruitRepository extends JpaRepository<Fruit, Long> {
    Optional<Fruit> findByName(String name, boolean isSold);
}
  • FruitReponse

public class FruitReponse {
    private String name;
    private LocalDate warehousingDate;
    private long price;
    private boolean isSold;
    private long id;

    public FruitReponse(String name, LocalDate warehousingDate,
                        long price, boolean isSold, long id) {
        this.name = name;
        this.warehousingDate = warehousingDate;
        this.price = price;
        this.isSold = isSold;
        this.id = id;
    }

    public FruitReponse(Fruit fruit) {
        this.name = getName();
        this.warehousingDate = getWarehousingDate();
        this.price = getPrice();
        this.isSold = getSold();
        this.id = getId();
    }

    public String getName() {
        return name;
    }
    public LocalDate getWarehousingDate() {
        return warehousingDate;
    }
    public long getPrice() {
        return price;
    }
    public boolean getSold() {
        return isSold;
    }
    public long getId() {
        return id;
    }
}
  • FruitRequest

    • FruitUpdateRequest

    public class FruitUpdateRequest {
        private long id;
        private String name;
    
        public long getId() {
            return id;
        }
        public String getName() {
            return name;
        }
    }
    • FruitCreateRequest

public class FruitCreateRequest {
    private String name;
    private LocalDate warehousingDate;
    private Integer price;
    private boolean isSold;
    private long id;

    public long getId() {
        return id;
    }
    public boolean getSold() {
        return isSold;
    }
    public String getName() {
        return name;
    }
    public LocalDate getWarehousingDate() {
        return warehousingDate;
    }
    public int getPrice() {
        return price;
    }

}
  • FruitService

@Service
public class FruitServiceV2 {
    private final FruitRepository fruitRepository;

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

    public void  saveFruit(FruitCreateRequest request) {
        Fruit fruit = fruitRepository.save(new Fruit(request.getName(),request.getPrice(), request.getSold(), request.getWarehousingDate()));
    }
    public List<FruitReponse> getFruit() {
        return fruitRepository.findAll().stream()
                .map(FruitReponse::new)
                .collect(Collectors.toList());
    }
    public void updateFruit(FruitUpdateRequest request) {
        Fruit fruit = fruitRepository.findById(request.getId())
                .orElseThrow(IllegalArgumentException::new);

        fruit.updateName(request.getName());
        fruitRepository.save(fruit);
    }
}

 

문제 2

우리는 특정 과일을 기준으로 지금까지 우리 가게를 거쳐갔던 과일 개수를 세고 싶습니다.

<문제 1>에서 만들었던 과일 Entity Class를 이용해 기능을 만들어 보세요

 

예를 들어

  1. (1, 사과, 3000원, 판매 O)

  2. (2, 바나나, 4000원, 판매 X)

  3. (3, 사과, 3000원, 판매 O)

와 같은 세 데이터가 있고, 사과를 기준으로 과일 개수를 센다면, 우리의 API는 2를 반환 할 것입니다.

 

구제적인 스펙은 다음과 같습니다.

  • HTTP method : GET

  • HTTP path : /api/v1/fruit/count

  • HTTP query

    • name : 과일 이름

  • 예시 GET /api/v1/fruit/count?name=사과

  • HTTP 응답 Body

image

  • HTTP 응답 Body예시

image

  •  FruitController

@GetMapping("/api/v1/fruit/count")
    public FruitCountResponse countFruit(@RequestParam String name) {
        return fruitService.countFruit(name);
    }
  •  FruitRepository

//Fruit 클래스
public void updateName(String name) {
        this.name = name;
    }

//FruitRepository 인터페이스
List<Fruit> findAllByName(String name);
  •  FruitJdbcRepository

public void countFruit(boolean isSold, long id) {
        String sql = "UPDATE fruit SET isSold = 1 WHERE id = ?";
        jdbcTemplate.update(sql, isSold, id);
    }
  • FruitService

    • FruitServiceV1

    public void countFruit(FruitCreateRequest request) {
            fruitJdbcRepository.countFruit(request.getSold(), request.getId());
        }
    • FruitServiceV2

public FruitCountResponse countFruit(String name) {
        long count = fruitRepository.findAllByName(name).stream().count();
        return new FruitCountResponse(count);
    }

 

문제 3

우리는 아직 판매되지 않은 특정 금액 이상 혹은 특정 금액 이하의 과일 목록을 받아보고 싶습니다.

구체적인 스펙은 다음과 같습니다.

  • HTTP method : GET

  • HTTP path : /api/v1/fruit/list

  • HTTP query

    • option : "GTE" 혹은 "LTE" 라는 문자열이 들어온다.

      • GTE : greater than equal 의 의미

      • LTE : less than equal 의 의미

    • price : 기준이 되는 금액이 들어온다.

  • 예시 1 - GET /api/v1/fruit/list?option=GTE&price=3000

    • 판매되지 않은 3000원 이상의 과일 목록을 반환해야 한다.

  • 예시 2 - GET /api/v1/fruit/list?option=LTE&price=5000

    • 판매되지 않은 5000원 이하의 과일 목록을 반환해야 한다.

  • HTTP 응답 Body

image

  • HTTP 응답 Body예시

image

  • FruitController

     

    @GetMapping("/api/v1/fruit/list")
        public List<FruitResponse> listFruit(@RequestParam String option, long price) {
            return fruitService.listFruit(option, price);
        }
  • FruitRepository

     

List<Fruit> findAllByPriceGreaterThanEqualAndIsSold(long price,boolean isSold);
List<Fruit> findAllByPriceLessThanEqualAndIsSold(long price,boolean isSold);
  •  FruitServiceV2

public List<FruitResponse> listFruit(String option, long price) {
        List<Fruit> fruits;
        if (option.equals("GTE")) {
            fruits = fruitRepository.findAllByPriceGreaterThanEqualAndIsSold(price, false);
        } else if (option.equals("LTE")) {
            fruits = fruitRepository.findAllByPriceLessThanEqualAndIsSold(price, false);
        } else {
            throw new IllegalArgumentException();
        }

        return fruits.stream()
                .map(FruitResponse::new)
                .collect(Collectors.toList());
    }

 

댓글을 작성해보세요.

채널톡 아이콘