@Entity
public class Fruit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id = null;
@Column(nullable = false, length = 20)
private String name;
private Integer price;
private LocalDate stocked_date;
@Column(nullable = false, columnDefinition = "BOOLEAN DEFAULT false")
private boolean sold;
public Fruit(String name, Integer price, LocalDate stocked_date) {
this.name = name;
this.price = price;
this.stocked_date = stocked_date;
}
public Fruit() {} //매개변수가 없는 기본 생성자
~~getter들은 코드가 너무 길어져 생략했다. 실제로는 코드가 존재함!!~~
public void updateSold(Long id) {
this.sold = true;
}
}
스프링이 테이블과 엔티티를 같은 것으로 바라보도록 어노테이션을 추가했다.
주의할 점은 jpa 객체(즉, 엔티티 객체)는 매개변수가 없는 기본 생성자가 꼭 필요하다는 것이다.
public interface FruitRepository extends JpaRepository<Fruit, Long> {
List<Fruit> findAllByNameAndSold(String name, boolean Sold);
}
findAllByNameAndSold 메소드는 판매여부(sold)에 따른 특정이름(name)의 과일객체들을 리스트로 반환한다.
@Service
public class FruitService {
private final FruitRepository fruitRepository;
public FruitService(FruitRepository fruitRepository) {
this.fruitRepository = fruitRepository;
}
public void saveFruit(FruitCreateRequest request) {
fruitRepository.save(new Fruit(request.getName(), request.getPrice(),request.getWarehousingDate()));
}
public void updateFruit(long id) {
Fruit fruit = fruitRepository.findById(id)
.orElseThrow(IllegalArgumentException::new);
fruit.updateSold(id);
fruitRepository.save(fruit);
}
public FruitStatResponse getFruitStat (String name) {
List<Fruit> fruitsSales = fruitRepository.findAllByNameAndSold(name, true);
List<Fruit> fruitsNotSales = fruitRepository.findAllByNameAndSold(name, false);
long salesAmount = 0;
for (Fruit oneOfFruit : fruitsSales) {
salesAmount += oneOfFruit.getPrice();
}
long notSalesAmount = 0;
for (Fruit oneOfFruit : fruitsNotSales) {
notSalesAmount += oneOfFruit.getPrice();
}
return new FruitStatResponse(salesAmount, notSalesAmount);
}
}
public interface FruitRepository extends JpaRepository<Fruit, Long> {
List<Fruit> findAllByNameAndSold(String name, boolean Sold);
long countByName(String name);
}
countByName 메소드를 추가했다.
이름을 받아 그 이름을 가진 객체의 개수를 반환한다.
@Service
public class FruitService {
~~ 문제 1에서의 서비스와 동일하므로 생략. 실제로는 이 중간에 코드가 존재함!! ~~
public FruitCountResponse getFruitCount(String name) {
long count = fruitRepository.countByName(name);
return new FruitCountResponse(count);
}
}
"count": 2로 결과가 잘 반환된 것을 확인할 수 있다.
public interface FruitRepository extends JpaRepository<Fruit, Long> {
List<Fruit> findAllByNameAndSold(String name, boolean sold);
long countByName(String name);
List<Fruit> findAllByPriceGreaterThanEqualAndSold(int price, boolean sold);
List<Fruit> findAllByPriceLessThanEqualAndSold(int price, boolean sold);
}
findAllByPriceGreaterThanEqualAndSold 메소드와
findAllByPriceLessThanEqualAndSold 메소드를 추가했다.
@Service
public class FruitService {
~~ 문제 2에서의 서비스와 동일하므로 생략. 실제로는 이 중간에 코드가 존재함!! ~~
public List<FruitListResponse> getFruitList(String option, int price) {
List<Fruit> fruits;
if(option.equals("GTE")){
fruits = fruitRepository.findAllByPriceGreaterThanEqualAndSold(price, false);
}
else if(option.equals("LTE")){
fruits = fruitRepository.findAllByPriceLessThanEqualAndSold(price, false);
}
else throw new IllegalArgumentException();
return fruits.stream()
.map(FruitListResponse::new)
.collect(Collectors.toList());
}
}
받은 option이 GTE인지 LTE인지에 따라 다른 메소드를 실행하도록 조건문으로 구현한다.
만약 둘 다 아닐 경우 에러를 던진다.
판매되지 않은 3000원 이상(greater than equal)의 과일 목록이 잘 반환된 것을 확인할 수 있다.