[인프런워밍업클럽][BE] 과제4 | 과일가게 API 만들기

문제 1.

1.1 DB 테이블 생성

  • HTTP 요청 body에 price가 long이기에 int 말고 bigint로 해 봄

  • primary key가 필요하여 수업에서 썼던 id 컬럼을 생성함.

image

1.2 StoreController

package com.group.libraryapp.controller.store;

import com.group.libraryapp.dto.store.request.FruitInsertRequest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class StoreController {

    //0. JdbcTemplate 사용하도록 연결
    private final JdbcTemplate jdbcTemplate;
    public StoreController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    //1. 과일 정보 저장
    @PostMapping("/api/v1/fruit")
    public void insertFruit(@RequestBody FruitInsertRequest request){
        String sql = "INSERT INTO fruit(name, warehousingDate, price) values(?,?,?)";
        jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice());
    }
    
}

 

1.3 FruitInsertRequest

  • html body에서 전송된 값을 java 변수 형식으로 변환해서 담아둘 dto가 필요하여 생성함

  • 정의된 형식에 맞춰서 생성.

package com.group.libraryapp.dto.store.request;

import java.util.Date;

public class FruitInsertRequest {

    public String name;
    public Date warehousingDate;
    public Long price;

    public String getName() {
        return name;
    }

    public Date getWarehousingDate() {
        return warehousingDate;
    }

    public Long getPrice() {
        return price;
    }
}

 

1.4 시연 결과

  • postman 결과

image

  • mysql 결과

    • 중간에 Date 값이 제대로 안들어갔다. 구글링하니 @JsonFormat이니 @DateTimeFormat이니 써보래서 써봤지만 소용이 없었다.

    • 강의록 앞부분을 다시 본 결과 warehousingDate (컬럼명)과 wareHousigDate(변수명)의 차이 때문이었다.

    • 대문자...차이..때문에... 30분은 날린 듯

image

하지만 다음 문제를 풀어야 해서 테이블을 다시 drop & create 후 데이터를 다시 넣어주었다.

image

 

위 API에서 가격에 대하여 int가 아니라 long을 사용한 이유는?

int에 비해 long이 표현할 수 있는 숫자의 양이 더 크다고 알고 있다. 그 외에 더 있을지도 모르지만..시간 상 생략..


 

문제 2.

  • 판매여부 데이터를 넣으라고 하는 문제

  • 근데, '판매여부' 관련 컬럼이 없다.

2.1 fruit 테이블에 컬럼 추가

  • fruit 테이블에 판매여부 값을 넣을 컬럼(soldout, 매진여부)을 추가한다.

    • bool 타입을 지원한다고 하는데, 사실상 tinyint(1)으로 저장된다기에 처음부터 tinyint(1) 형식으로 만듦

    • 처음 입고된 시점에는 soldout 되었을 리 없으므로, 0(false)를 기본값으로 넣었다.

alter table `fruit` add column `soldout` tinyint(1) default 0;

image

  • 기본값을 0으로 설정했기에, 그 전에 들어있던 데이터들도 해당 컬럼에 0으로 들어가 있는 것을 확인할 수 있다.

image

2.2 StoreController : sellFruit()

  • 예외처리도 배웠겠다, 해당 id의 상품이 없으면 예외처리 하란 얘기렸다?

    • 사실 sql 문으로 없으면 false를 내뱉도록 짤까 생각했지만, (이건 간단하지만) 그런 자잘한 쿼리 하나하나가 DB에 부담을 줄 것 같아서 배운대로 했다.

    • 일단은 isEmpty()를 활용했는데, 주말에는 이것 외에 다른 방법은 없는지 좀 더 공부해보자.

  • 판매 시 호출하는 함수이므로, soldout = ? 할 필요 없이 바로 soldout = 1로 주었다.

  •  

    //2. 팔린 과일 정보 저장
    @PutMapping("/api/v1/fruit")
    public void sellFruit(@RequestParam long id){
        // 해당 id의 상품 존재 여부 파악
        String selectSql = "SELECT * FROM fruit WHERE id = ?";
        boolean fruitNotExist = jdbcTemplate.query(selectSql, (rs, rowNum) -> 0, id).isEmpty();
        if(fruitNotExist){throw new IllegalArgumentException();}

        // 판매여부 데이터 업데이트
        String updateSql = "UPDATE fruit SET soldout = 1 WHERE id = ?";
        jdbcTemplate.update(updateSql, id);
    }

 

2.3 결과

  • 예시에서 1, 3번이 팔렸으므로

image

  • DB 조회 결과

image

  • 예외 처리 결과

image

 


문제 3

3.1 price 수정

  • 예제의 가격이 달라서 price 수정함

update fruit set price = 3000 where id = 1;
update fruit set price = 4000 where id = 2;
update fruit set price = 3000 where id = 3;

3.2 StoreController

  • 시간이 없어서 일단 된 곳까지 제출함

  • 근데 포스트맨으로 결과 내고나서 문제지랑 비교하니까.. 아 결과를 잘못 냈다..

  • HTTP 응답 형식 맞게 다시 만들어야지ㅠㅠ

//3. 판매/미판매 금액 조회
    @GetMapping("/api/v1/fruit/stat")
    public List<FruitStatsResponse> descStoreInfo(){
        String sql = "SELECT f.soldout, sum(f.price) as amt FROM fruit f GROUP BY f.soldout";

        return jdbcTemplate.query(sql, (rs,rowNum) -> {
            int soldout = rs.getInt("soldout");
            long amount = rs.getLong("amt");

            if(soldout==1){}

            return new FruitStatsResponse(soldout,amount);
        });

    }

 

3.3 FruitStatsResponse

public class FruitStatsResponse {

    private int soldout;
    private long amount;

    public FruitStatsResponse(int soldout, long amount) {
        this.soldout = soldout;
        this.amount = amount;
    }

    public int getSoldout() {
        return soldout;
    }

    public long getAmount() {
        return amount;
    }
}

 

3.4 현재 결과

ㅠㅠㅠㅠ 고쳐야 함..

image

 

댓글을 작성해보세요.

채널톡 아이콘