[인프런 워밍업 클럽] BE 0기 4일차 과제
9개월 전
컨트롤러)
@RestController
public class WorkController {
private JdbcTemplate jdbcTemplate;
public WorkController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@PostMapping("/api/v1/fruit")
public void saveFruit(@RequestBody FruitRequest request) {
String sql = "insert into fruit (name, warehousing_date, price) values (?, ?, ?)";
jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice());
}
}
fruit Table 생성)
create table fruit(
id bigint auto_increment,
name varchar(30),
warehousing_date date,
price bigint,
primary key (id)
);
POST요청 Body를 받기 위한 FruitRequestDTO 생성)
import java.time.LocalDate;
public class FruitRequest {
private String name;
private LocalDate warehousingDate;
private long price;
public String getName() {
return name;
}
public LocalDate getWarehousingDate() {
return warehousingDate;
}
public long getPrice() {
return price;
}
}
결과)
정상적으로 데이터베이스에 저장된 것을 확인 할 수 있었다.
int type은 4바이트로서 최대 정수의 범위가 약 21억까지밖에 표현을 할 수 없기 때문에, 가격의 총 합과 같은 경우를 생각해본다면, 21억이 넘는 숫자는 빈번히 발생한다. 그렇기 때문에 8바이트인 long type을 사용하여 오버플로우를 방지하기 위해 사용한 것 이라고 생각한다.
기존 테이블에는 품절 여부를 확인할 수 있는 속성이 없었기 때문에 속성을 추가해주었다.
alter table fruit add column is_sold boolean default false;
컨트롤러)
public class WorkController {
private JdbcTemplate jdbcTemplate;
public WorkController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@PutMapping("/api/v1/fruit")
public void saleFruit(@RequestBody SoldOutFruitRequest request) {
String readSql = "select id from fruit where id = ? and is_sold = false";
boolean isEmpty = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
if (isEmpty){
throw new IllegalArgumentException();
}
String sql = "update fruit set is_sold = true where id = ?";
jdbcTemplate.update(sql, request.getId());
}
}
이미 품절 되었나 확인해보기 위해 조건을 확인하는 read 쿼리를 만들어 확인 후 이미 팔렸다면 예외 처리를 해주었다.
BODY 데이터를 받기 위한 SoldOutFruitRequest)
public class SoldOutFruitRequest {
private long id;
public long getId() {
return id;
}
}
결과)
컨트롤러)
@RestController
public class WorkController {
private JdbcTemplate jdbcTemplate;
public WorkController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@GetMapping("/api/v1/fruit/stat")
public TotalPriceResponse salesData(@RequestParam String name) {
String salesRead = "select price from fruit where name = ? and is_sold = true";
List<Long> price = jdbcTemplate.query(salesRead, (rs, rowNum) -> rs.getLong("price"), name);
String notSalesRead = "select price from fruit where name = ? and is_sold = false";
List<Long> price1 = jdbcTemplate.query(notSalesRead, (rs, rowNum) -> rs.getLong("price"), name);
return new TotalPriceResponse(price.stream().mapToLong(i -> i).sum(),
price1.stream().mapToLong(i -> i).sum());
}
}
팔린 품목들의 합과 안팔린 품목들의 합을 구하기 위해 read 쿼리를 두번 날려보았다.
이후 출력을 위해 Response객체를 만들어주었다.
TotalPriceResponse)
public class TotalPriceResponse {
private long salesAmount;
private long notSalesAmount;
public TotalPriceResponse(long salesAmount, long notSalesAmount) {
this.salesAmount = salesAmount;
this.notSalesAmount = notSalesAmount;
}
public long getSalesAmount() {
return salesAmount;
}
public long getNotSalesAmount() {
return notSalesAmount;
}
}
결과)
추가적으로 DB에서 처리하여 가져올 수 있도록 sum과, group by를 써서 만들어 보았다.
@GetMapping("/api/v1/fruit/stat")
public TotalPriceResponse salesData(@RequestParam String name) {
String salesRead = "select sum(price) price from fruit where name = ? and is_sold = true";
List<Long> price = jdbcTemplate.query(salesRead, (rs, rowNum) -> rs.getLong("price"), name);
String notSalesRead = "select price from fruit where name = ? and is_sold = false group by price";
List<Long> price1 = jdbcTemplate.query(notSalesRead, (rs, rowNum) -> rs.getLong("price"), name);
return new TotalPriceResponse(price.get(0), price1.get(0));
}
팔린 품목에 대해서는 sum 함수를, 안팔린 품목에 대해서는 group by절을 추가하여 사용한 형태이다.
다만 where절의 항목에 없을경우 예외처리를 해줘야 하는 부분이 있다.
댓글을 작성해보세요.