@Entity
@Getter
public class Fruit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 20)
private String name;
@Column(nullable = false)
private LocalDate warehousingDate;
@Column(nullable = false)
private long price;
@Column(nullable = false, columnDefinition = "boolean default false")
private Boolean purchase;
public Fruit(String name, LocalDate warehousingDate, long price) {
this.name = name;
this.warehousingDate = warehousingDate;
this.price = price;
this.purchase = false;
}
public Fruit() {
}
public void updatePurchase(){
this.purchase = true;
}
}
@Service
public class FruitService {
private final FruitRepository fruitRepository;
public FruitService(FruitRepository fruitRepository) {
this.fruitRepository = fruitRepository;
}
@Transactional
public void addFruit(FruitCreateRequest request){
fruitRepository.save(new Fruit(request.getName(), request.getWarehousingDate(), request.getPrice()));
}
@Transactional
public void updateFruit(FruitUpdateRequest request) {
Fruit fruit = fruitRepository.findById(request.getId())
.orElseThrow(IllegalAccessError::new);
fruit.updatePurchase();
}
@Transactional
public FruitAmountResponse showAmount(String name) {
long salesAmount = fruitRepository.findAllByNameAndPurchase(name, true)
.stream()
.mapToLong(Fruit::getPrice)
.sum();
long notSalesAmount = fruitRepository.findAllByPurchase(false)
.stream()
.mapToLong(Fruit::getPrice)
.sum();
return new FruitAmountResponse(salesAmount, notSalesAmount);
}
}
@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
List<Fruit> findAllByNameAndPurchase(String name, boolean b);
List<Fruit> findAllByPurchase(boolean b);
}
우리는 특정 과일을 기준으로 지금까지 우리 가게를 거쳐갔던 과일 개수를 세고 싶습니다.
<문제 1>에서 만들었던 과일 Entity Class를 이용해 기능을 만들어 보세요!
예를 들어
와 같은 데이터가 있고, 사과를 기준으로 과일 개수를 센다면, API는 2를 반환할 것입니다.
구체적인 스펙은 다음과 같습니다.
**GET****/api/v1/fruit/count****GET /api/v1/fruit/count?name=사과@RestController
public class FruitController {
@GetMapping("/api/v1/fruit/count")
public FruitCountResponse showCount(@RequestParam String name) {
return fruitService.showCount(name);
}
}
@Service
public class FruitService {
public FruitCountResponse showCount(String name) {
long count = fruitRepository.findByName(name)
.stream()
.count();
return new FruitCountResponse(count);
}
}
@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
List<Fruit> findByName(String name);
}
public class FruitCountResponse {
private long count;
public FruitCountResponse(long count) {
this.count = count;
}
public long getCount() {
return count;
}
}
우리는 아직 판매되지 않은 특정 금액 이상 혹은 특정 금액 이하의 과일 목록을 받아보고 싶습니다.
구체적인 스펙은 다음과 같습니다.
**GET****/api/v1/fruit/list**GET /api/v1/fruit/list?option=GTE&price=3000**GET /api/v1/fruit/list?option=LTE&price=5000**@RestController
public class FruitController {
@GetMapping("/api/v1/fruit/list")
public List<FruitListResponse> showList(@RequestParam String option,
@RequestParam long price){
return fruitService.showList(option, price);
}
}
@Service
public class FruitService {
public List<FruitListResponse> showList(String option, long price) {
List<Fruit> fruits = null;
if(option.equals("GTE")) {
fruits = fruitRepository.findByPriceGreaterThanEqual(price);
}
else if(option.equals("LTE")){
fruits = fruitRepository.findByPriceLessThanEqual(price);
}
if(fruits == null) throw new IllegalArgumentException("검색 결과 없음");
return fruits.stream().filter(fruit -> !fruit.getPurchase())
.map(fruit -> new FruitListResponse(fruit.getName(), fruit.getPrice(), fruit.getWarehousingDate()))
.toList();
}
}
@Repository
public interface FruitRepository extends JpaRepository<Fruit, Long> {
...
List<Fruit> findByPriceGreaterThanEqual(long price);
List<Fruit> findByPriceLessThanEqual(long price);
}
public class FruitListResponse {
private String name;
private long price;
private LocalDate warehousingDate;
public FruitListResponse(String name, long price, LocalDate warehousingDate) {
this.name = name;
this.price = price;
this.warehousingDate = warehousingDate;
}
public String getName() {
return name;
}
public long getPrice() {
return price;
}
public LocalDate getWarehousingDate() {
return warehousingDate;
}
}