ABOUT ME

Today
Yesterday
Total
  • 인프런 워밍업 클럽/ BE 7일차 과제 : JPA 마이그레이션
    인프런 워밍업 클럽 2024. 5. 16. 22:19

    7일차 과제

    문제 1

    Fruit 도메인

    JPA를 사용하기 위해 Fruit도메인을 만들어서 Entity로 만들었다.

    @Entity
    public class Fruit {
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Id
        private long id;
    
        @Column(nullable = false)
        private String name;
    
        @Column(nullable = false, name = "warehousing_date")
        private LocalDate warehousingDate;
    
        @Column(nullable = false)
        private long price;
    
        @Column(nullable = false)
        private boolean state;
    
        protected Fruit() {}
    
        public long getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public LocalDate getWarehousingDate() {
            return warehousingDate;
        }
    
        public long getPrice() {
            return price;
        }
    
        public boolean isState() {
            return state;
        }
    
        public Fruit(FruitRequestDTO request) {
            this.name = request.getName();
            this.warehousingDate = request.getWarehousingDate();
            this.price = request.getPrice();
            this.state = false;
        }
        public void updateFruit() {
            this.state = true;
        }
    }

     

     

    컨트롤러는 JPA를 사용해도 똑같이 요청과 응답의 기능을 해주기 때문에 기존의 컨트롤러를 그대로 사용한다.

     

    FruitServiceV2

    서비스단의 경우는 V2를 새롭게 만들어서 사용했다. 

    @Service
    public class FruitServiceV2 {
        private final FruitRepositoryV2 fruitRepositoryV2;
        public FruitServiceV2(FruitRepositoryV2 fruitRepositoryV2) {
            this.fruitRepositoryV2 = fruitRepositoryV2;
        }
    
        public void storeFruit(FruitRequestDTO request) {
            Fruit fruit = fruitRepositoryV2.save(new Fruit(request));
        }
    
        public void updateFruit(FruitUpdateRequestDTO request) {
            Fruit fruit = fruitRepositoryV2.findById(request.getId())
                            .orElseThrow(IllegalArgumentException::new);
            fruit.updateFruit();
        }
    
        public FruitAmountResponse getFruitAmount(String name) {
            int salesAmount = fruitRepositoryV2.getSalesAmountByName(name);
            int notSalesAmount = fruitRepositoryV2.getNotSalesAmountByName(name);
            return new FruitAmountResponse(salesAmount,notSalesAmount);
        }

    Update문의 경우, JPA Persistence를 이용해서 내부에서 로직을 처리하도록 했다.

     

    FruitRepositoryV2

    리포지토리도 V2로 새롭게 인터페이스로 만들고, JpaRepository를 상속받았다.

    public interface FruitRepositoryV2 extends JpaRepository<Fruit,Long> {
        @Query(value = "SELECT sum(price) FROM fruit WHERE state=1 AND name=:name", nativeQuery = true)
        int getSalesAmountByName(String name);
    
        @Query(value = "SELECT sum(price) FROM fruit WHERE state=0 AND name=:name", nativeQuery = true)
        int getNotSalesAmountByName(String name);
    }

    JpaRepository를 사용하기 어려운 쿼리문은 새롭게 추상 메서드를 만들어서 사용했다.

     


    문제2

    출처 : 인프런 -  자바와 스프링 부트로 생애 최초 서버 만들기

     

    FruitController

        //과일 총합
        @GetMapping("/api/v1/fruit/stat")
        public FruitAmountResponse getFruitAmount(@RequestParam String name) {
            return fruitServiceV2.getFruitAmount(name);
        }

     

    FruitServiceV2

        public FruitCountResponse getCountByName(String name) {
            return new FruitCountResponse(fruitRepositoryV2.getCountByName(name));
        }

     

    FruitRepositoryV2

        @Query(value = "SELECT COUNT(id) FROM fruit WHERE name = :name", nativeQuery = true)
        long getCountByName(String name);


    결과값


    문제3

    출처 : 인프런 -  자바와 스프링 부트로 생애 최초 서버 만들기

     

    FruitController

        //과일 리스트
        @GetMapping("/api/v1/fruit/list")
        public List<FruitResponse> getFruitList(@RequestParam String option, long price) {
            return fruitServiceV2.getFruitList(option, price);
        }

     

    FruitServiceV2

    public List<FruitResponse> getFruitList(String option, long price) {
            if(option.equals("GTE")) {
                List<Fruit> list = fruitRepositoryV2.findAllByGTEPrice(price);
                List<FruitResponse> fruitList = list.stream()
                        .map(fruit -> new FruitResponse(fruit.getName(), fruit.getPrice(),fruit.getWarehousingDate()))
                        .collect(Collectors.toList());
                return fruitList;
    
            }
            else if(option.equals("LTE")) {
                List<Fruit> list = fruitRepositoryV2.findAllByLTEPrice(price);
                List<FruitResponse> fruitList = list.stream()
                        .map(fruit -> new FruitResponse(fruit.getName(), fruit.getPrice(),fruit.getWarehousingDate()))
                        .collect(Collectors.toList());
                return fruitList;
            }
            else {
                throw new IllegalArgumentException();
            }
    
        }

    Option이 GTE일 경우와 LTE일 경우를 비즈니스 로직에서 처리해준다.

    리포지토리에서 Fruit리스트를 받고 stream을 사용해서 FruitResponse리스트로 매핑해준다.


    FruitRepositoryV2

        @Query(value = "SELECT * FROM fruit WHERE price >= :price AND state = 0", nativeQuery = true)
        List<Fruit> findAllByGTEPrice(long price);
    
        @Query(value = "SELECT * FROM fruit WHERE price <= :price and state = 0", nativeQuery = true)
        List<Fruit> findAllByLTEPrice(long price);

     

    결과값

     

Designed by Tistory.