인프런 워밍업 클럽 스터디 1기 BE 4번째 과제
7개월 전
문제1
과일 정보 저장 API
{
"name": "사과",
"warehousingDate": "2024-02-01",
"price": 5000
}
위와 같은 정보를 받아서 저장할 수 있도록 fruit 테이블을 만들었다.
create table fruit (
id bigint auto_increment,
name varchar(30),
warehousingdate date,
price bigint,
primary key(id)
);
그리고 이전에 구현했던 내용과 똑같이 INSERT문을 이용해 과일 정보 저장 API를 구현했다.
public void save(Fruit fruit) {
String sql = "INSERT INTO fruit (name, warehousingdate, price) VALUES (?, ?, ?)";
jdbcTemplate.update(sql, fruit.getName(), fruit.getWarehousingDate(), fruit.getPrice());
}
가격을 나타내는 price의 테이터 타입은 long을 사용했는데
int를 사용하지 않고 long을 사용하는 이유는
가격의 크기가 int의 범위를 초과할 수 있기 때문이다.
문제2
문제2는 과일이 팔린 경우 팔렸다는 정보를 저장하는 API를 구현하는 문제
팔렸다는 정보를 저장하기 위해서 fruit 테이블에 sold
라는 컬럼을 추가했다.
create table fruit (
id bigint auto_increment,
name varchar(30),
warehousingdate date,
price bigint,
sold boolean default false,
primary key(id)
);
boolean 타입이고 default 값은 false인 sold
컬럼을 만들어서
과일이 팔린 경우 해당 API를 호출하면 sold
컬럼을 true로 바꿔주도록 구현헀다.
public void updateSold(Long id) {
String sql = "UPDATE fruit SET sold = true WHERE id = ?";
jdbcTemplate.update(sql, id);
}
문제3
특정 과일의 팔린 금액과 팔리지 않은 금액을 조회하는 API 구현하기
2가지의 방법으로 구현할 수 있다.
1. 과일의 이름에 해당하는 모든 데이터를 조회해서 Service 단에서 금액을 계산하기
FruitRepository
public List<Fruit> getStat(String name) {
String sql = "SELECT name, price, sold FROM fruit WHERE name = ?";
return jdbcTemplate.query(sql, (rs, rowNum) -> new Fruit(
rs.getString("name"),
rs.getLong("price"),
rs.getBoolean("sold")
), name);
}
FruitService
public FruitStatResponse getStat(String name) {
List<Fruit> fruits = fruitRepository.getStat(name);
long salesAmount = 0;
long notSalesAmount = 0;
for (Fruit fruit : fruits) {
if (fruit.getSold()) {
salesAmount += fruit.getPrice();
} else {
notSalesAmount += fruit.getPrice();
}
}
return new FruitStatResponse(salesAmount, notSalesAmount);
}
데이터가 다음과 같이 들어있을 경우
원하는 결과를 조회할 수 있다.
2. 팔린 금액과 팔리지 않은 금액을 조회하는 쿼리를 만들기
public FruitStatResponse getStat(String name) {
String sql = "SELECT SUM(CASE WHEN sold = true THEN price ELSE 0 END) salesamount, "
+ "SUM(CASE WHEN sold = false THEN price ELSE 0 END) notsalesamount "
+ "FROM fruit WHERE name = ?";
return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> new FruitStatResponse(
rs.getLong("salesamount"),
rs.getLong("notsalesamount")
), name);
}
SUM 함수를 사용해서 금액의 합을 계산할 수 있고
CASE문을 사용하면 sold
가 true인 금액을 조건으로 해서 계산할 수 있다.
이렇게 쿼리를 이용하면 다양한 조건의 데이터를 검색할 수 있기 때문에
Service단에서 원하는 데이터를 분류하는 작업을 하지 않을 수 있다.
SQL을 잘 알면 활용할 수 있는 방법이 무궁무진 하지만
SQL도 알면 알수록 더 어려워지는 것 같다…
댓글을 작성해보세요.