[인프런워밍업클럽][BE] 과제4 | 과일가게 API 만들기
문제 1.
1.1 DB 테이블 생성
HTTP 요청 body에 price가 long이기에 int 말고 bigint로 해 봄
primary key가 필요하여 수업에서 썼던 id 컬럼을 생성함.
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 결과
mysql 결과
중간에 Date 값이 제대로 안들어갔다. 구글링하니 @JsonFormat이니 @DateTimeFormat이니 써보래서 써봤지만 소용이 없었다.
강의록 앞부분을 다시 본 결과 warehousingDate (컬럼명)과 wareHousigDate(변수명)의 차이 때문이었다.
대문자...차이..때문에... 30분은 날린 듯
하지만 다음 문제를 풀어야 해서 테이블을 다시 drop & create 후 데이터를 다시 넣어주었다.
위 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;
기본값을 0으로 설정했기에, 그 전에 들어있던 데이터들도 해당 컬럼에 0으로 들어가 있는 것을 확인할 수 있다.
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번이 팔렸으므로
DB 조회 결과
예외 처리 결과
문제 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 현재 결과
ㅠㅠㅠㅠ 고쳐야 함..
댓글을 작성해보세요.