[인프런 워밍업 클럽 스터디1기] 백엔드 - 7차 과제

[인프런 워밍업 클럽 스터디1기] 백엔드 - 7차 과제

진도표 7일차와 연결됩니다

우리는 JPA라는 개념을 배우고 유저 테이블에 JPA를 적용해 보았습니다. 몇 가지 문제를 통해 JPA를 연습해 봅시다! 🔥

 

 

 

 

 


문제1

JPA(Java Persistence API) 는 자바 객체를 관계형 데이터 베이스에 영속적으로 저장하고 조회할 수 있는 ORM 기술에 대한 표준 명세를 의미한다.

JPA 를 통해 SQL 쿼리를 작성하지 않고도 객체를 통해 데이터베이스를 조작할 수 있어 보수성이 향상된다.

Entity 클래스를 작성한 후 Repository 인터페이스를 생성해야하는데, JpaRepository를 상속받도록 하면, 기본적인 쿼리 추가, 조회, 수정, 삭제, findAll(), findById() 등의 메서드를 사용할 수 있다.

1) Entity 클래스 정의

@Entity
public class Fruits {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = null;
    @Column(nullable = false, length = 20 )
    private String name;
    @Column(nullable = false)
    private LocalDate warehousingDate;
    @Column(nullable = false)
    private long price;
    @Column(nullable = false)
    private int saled;

    public Fruits(){

    }
    public Fruits(long id, String name, LocalDate warehousingDate, long price, int saled) {
        this.id = id;
        this.name = name;
        this.warehousingDate = warehousingDate;
        this.price = price;
        this.saled = saled;
    }

    public Fruits(String name, LocalDate warehousingDate, long price, int saled) {
        this.name = name;
        this.warehousingDate = warehousingDate;
        this.price = price;
        this.saled = saled;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public LocalDate getWarehousingDate() {
        return warehousingDate;
    }

    public long getPrice() {
        return price;
    }

    public int getSaled(){
        return saled;
    }

    public void setSaled(int saled) {
        this.saled = saled;
    }
}

JPARepository를 사용하여 액세스할 엔티티 클래스를 정의했다.

@Entity 어노테이션은 JPA를 사용해 테이블과 매핑할 클래스에 붙여주는 어노테이션이다. 이 어노테이션을 붙이면, JPA가 해당 클래스를 관리하게 된다.

@Id 어노테이션은 특정 속성을 기본키로 설정하는 어노테이션이다.

@GeneratedValue(startegy = GenerationType.IDENTITY) 은 기본키 생성을 DB에 위임한다는 것으로 위 클래스에서는 id 값이 자동 생성된다.

@Column 은 객체필드를 테이블 칼럼과 매핑한다.

 

2) JpaRepository 인터페이스 상속받는 인터페이스 생성

public interface FruitRepository extends JpaRepository<Fruits,Long> {
    Optional<Fruits> findById(Long id);
    long countByNameAndSaled(String name,int i);

    long countByName(String name);

    List<Fruits> findByPriceGreaterThan(long price);

    List<Fruits> findByPriceLessThan(long price);

    List<Fruits> findBySaled(int i);
}

 

문제2

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

controller 클래스에서는 아래와 같이 getmapping 부분을 만들고

@GetMapping("/api/v1/fruit/count")
    @Description("지금까지 거쳐간 특정 과일이름의 개수를 반환(7일차-문제2)")
    public FruitCountResponse countName(@RequestParam String name){
        return fruitService.countName(name);
    }

service 클래스에서는 

 public FruitCountResponse countName(String name) {
        Long result = fruitRepository.countByName(name);
        return new FruitCountResponse(result);
    }

위와 같이 FruitCountResponse 객체를 반환하도록 한다.

FruitCountResponse  클래스는 아래와 같이 간단하게 json 형식으로 "count" : 숫자 를 반환하도록 만들었다.

public class FruitCountResponse {
  private long count;

  public FruitCountResponse(long count) {
    this.count = count;
  }

  public long getCount() {
    return count;
  }
}

아래와 같이 HTTP 응답 Body 예시와 같은 형식으로 나오는 것을 볼 수 있다.

 

 

문제3

 

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

controller 클래스에서는 

@GetMapping("/api/v1/fruit/list")
    @Description("판매되지 않은 특정 금액 이상 혹은 특정 금액 이하의 과일 목록(7일차-문제3)")
    public List<Fruits> getListFruit(@RequestParam String option, @RequestParam long price){
        return fruitService.overviewFruitCondition(option,price);
    }

service 클래스에서는

public List<Fruits> overviewFruitCondition(String option, long price) {
        List<Fruits> list;
        List<Fruits> result = new ArrayList<>();
        if (option.equals("GTE"))
            list = fruitRepository.findByPriceGreaterThan(price);
        else if (option.equals("LTE")){
            list = fruitRepository.findByPriceLessThan(price);
        }else
            throw new IllegalArgumentException("GTE, LTE 로 작성해주세요.");

        for (Fruits e : list)
            if (e.getSaled() == 1)
                result.add(e);
        return result;
    }

위와 같이 List<Fruits> 를 반환하도록 한다. 

 

 

위와 같이 조건을 만족하는 (6000 이하의 과일들) 결과를 출력한다.

 

회고

직접 JpaRepository를 상속받는 repository와 entity 를 만들어 실습해보니, 약간 익숙해진 것 같다. 

위 과제를 하는 중간중간 오류(1,2) 가 났었는데,

1) getter of property ‘id’ threw exception

https://stackoverflow.com/questions/25234892/org-springframework-beans-invalidpropertyexception-invalid-property-id-of-bea

 

org.springframework.beans.InvalidPropertyException: Invalid property 'id' of bean class

I dont understand why I am getting this error on the save below. Any clue? org.springframework.beans.InvalidPropertyException: Invalid property 'id' of bean class [com.test.DataException]: Getter...

stackoverflow.com

위 오류에서는 long에서 Long으로 id 타입을 바꾸니 해결되었다.

2) Unknown column 'warehousing_date' in 'field list'

위 오류에서는 warehousing_date 라는 칼럼명을 못 찾아서 데이터를 save 할 수 없는 상황이였는데,

변수 값을 잘못 넣어서 오류가 났던 거라 바꾸니 해결되었다.

댓글을 작성해보세요.

채널톡 아이콘