[인프런 워밍업 클럽 0기] BE 4일차 과제
문제 1
하기전에 테이블을 작성을 합니다.
create table fruit
(
id bigint auto_increment,
name varchar(20),
warehousingDate date,
price bigint,
is_sale boolean default 0,
primary key (id)
);
과일 정보 저장하는 API
요청을 받기 위해 FruitRequest 를 만듭니다.
@Data
public class FruitRequest {
private String name;
private LocalDate warehousingDate;
private long price;
}
요청을 받고 쿼리문을 날려 저장하는 비지니스 로직을 만듭니다.
@AllArgsConstructor
@Service
public class FruitService {
private final JdbcTemplate jdbcTemplate;
public void save(FruitRequest request) {
String sql = "insert into fruit (name, warehousingDate, price) " +
"values (?, ? ,?)";
jdbcTemplate.update(sql,
request.getName(),
request.getWarehousingDate(),
request.getPrice());
}
}
FruitService 클래스를 만들어 데이터 삽입sql을 만들고 jdbcTemplate로 업데이트 해주는 비지니스 로직을 만듭니다.
@AllArgsConstructor
@RestController
@RequestMapping("/api/v1/fruit")
public class FruitController {
private final FruitService fruitService;
@PostMapping
public ResponseEntity<?> savedFruit(@RequestBody FruitRequest request) {
fruitService.save(request);
return ResponseEntity.ok().build();
}
}
FruitController를 만들어 비지니스 처리를 완료하면 정상 응답을 내리는 메서드를 만들면 됩니다.
int 와 long 사이에 long을 사용하는 이유는 표현 범위 때문입니다.
long 이 int 보다 월등히 많은 수를 표현하기 때문입니다.
문제 2
과일 팔리면 과일 정보 기록 API
응답을 받기 위해 FruitStateRequest 클래스를 만듭니다.
@Data
public class FruitStateRequest {
private Long id;
}
비즈니스 로직을 수행하기 위해 FruitService 크랠스에서 다음과 같은 메서드를 작성합니다.
public void stateUpdate(FruitStateRequest request) {
String fruitSql = "select * from fruit where id = ?";
boolean isFruitNotExist = jdbcTemplate
.query(fruitSql, (rs, rowNum) -> 0,
request.getId()).isEmpty();
if (isFruitNotExist) {
throw new IllegalStateException("일치하는 과일 정보가 없습니다.");
}
String sql = "update fruit set is_sale = 1 where id = ?";
jdbcTemplate.update(sql, request.getId());
}
먼저 해당 id로 과일 정보가 있는지 확인을 합니다.
없으면 일치하는 과일 정보가 없다고 경고를 주고 있으면 업데이트 sql문으로 업데이트 쿼리를 날립니다.
@PutMapping
public ResponseEntity<?> FruitStateUpdate(@RequestBody FruitStateRequest request) {
fruitService.stateUpdate(request);
return ResponseEntity.ok().build();
}
FruitController에 put요청을 받기 위한 메서드를 만들고 정상으로 수행이 되면 200 요청을 보냅니다.
문제 3
특정 과일 기준으로 팔린 금액과 팔리지 않은 금액 조회
먼저 수행하기전 테이블에 과일 정보를 입력해둡니다.
FruitController 에 과일 이름 파라미터를 받고 처리하기 위해 메서드를 만듭니다.
@GetMapping("/stat")
public ResponseEntity<?> isSaleStateTotalPrice(@RequestParam String name) {
return ResponseEntity.ok(fruitService.getSum(name));
}
서비스 로직에서 정상 수행을 하면 결과값을 반환하게 만들었습니다.
이제 비지니스로직을 FruitService에 작성해줍시다
public FruitTotalPriceResponse getSum(String name) {
String fruitSql = "select * from fruit where name = ?";
boolean isFruitNotExist = jdbcTemplate
.query(fruitSql, (rs, rowNum) -> 0,
name).isEmpty();
if (isFruitNotExist) {
throw new IllegalStateException("일치하는 과일 정보가 없습니다.");
}
String sql = "select is_sale, sum(price) as totalPrice from fruit " +
"where name = ? group by is_sale";
List<FruitTotalPriceResponse> results = jdbcTemplate.query(sql, new Object[]{name},
(rs, rowNum) -> new FruitTotalPriceResponse(
rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0,
!rs.getBoolean("is_sale") ? rs.getLong("totalPrice") : 0));
long salesAmount = 0;
long noSalesAmount = 0;
for (FruitTotalPriceResponse result : results) {
salesAmount += result.getSalesAmount();
noSalesAmount += result.getNoSalesAmount();
}
return new FruitTotalPriceResponse(salesAmount, noSalesAmount);
과일 이름으로 과일 정보가 있는지 확인합니다.
없으면 에러를 일으키고 있다면 다음 로직을 수행합니다.
과일이 팔렷는지 아닌지 확인을 위해 is_sale 그룹으로 해당 과일의 is_sale와 price 합계를 구합니다.
그리고 쿼리문으로 리스트 결과를 받아 각각의 합계를 구한후 리턴합니다.
매번 repository로 하던 습관으로 하다보니 간만에 jdbcTemplate 으로 하는데 꽤나 예를 먹은 과제인거 같다.
댓글을 작성해보세요.