우리는 작은 과일 가게를 운영하고 있습니다. 과일 가게에 입고된 '과일 정보'를 저장하는 API를 만들어 봅시다. 스펙은 다음과 같습니다.
POST
/api/v1/fruit
{
"name" : String,
"warehousingDate" : LocalDate,
"price" : long
}
feat-GPT…
int
타입은 최대 약 21억 (2^31 - 1
)까지의 값을 저장할 수 있습니다. 반면, long
타입은 약 922경 (2^63 - 1
)까지 저장할 수 있습니다. 금융이나 상업 분야에서는 종종 매우 큰 수치를 다루어야 하며, int
의 범위가 부족할 수 있습니다.long
을 사용하면 값의 오버플로우(값이 너무 커서 변수의 저장 범위를 넘어서는 상황) 위험을 줄일 수 있습니다. 이는 특히 금융 애플리케이션에서 중요한 고려 사항입니다.long
을 사용하면 이러한 다양성을 더 잘 수용할 수 있습니다.int
범위 내에서 충분할지라도, 비즈니스가 성장하면서 더 큰 수치를 다루어야 할 필요성이 생길 수 있습니다. 처음부터 long
을 사용함으로써 나중에 발생할 수 있는 범위 문제를 예방할 수 있습니다.+추가
박싱타입(Integer, Long)과 기본타입(int, long)의 가장 큰 차이점은 null을 사용할 수 있냐 없냐 차이이다.
{
"timestamp": "2024-02-22T14:35:37.716+00:00",
"status": 404,
"error": "Not Found",
"path": "/api/v2/fruit"
}
(nam:”사과”) 처럼 오타를 내도 값이 null로 들어갔다.
2번 이후 is_sale을 추가했다.
CREATE DATABASE library;
USE library;
SHOW TABLES;
CREATE TABLE fruit(
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20),
warehousingDate DATETIME,
price INT,
is_saled BOOLEAN DEFAULT true
);
select * from fruit;
DROP TABLE fruit;
package com.group.libraryapp.controller;
import com.group.libraryapp.dto.FruitRequest;
import com.group.libraryapp.service.FruitService;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/v2")
public class FruitController {
JdbcTemplate jdbcTemplate;
FruitService fruitService;
public FruitController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
this.fruitService = new FruitService(jdbcTemplate);
}
@PostMapping("/fruit")
public void saveFruit(@RequestBody FruitRequest request){
fruitService.saveFruit(request);
}
@PutMapping("/fruit")
public void sellFruit(@RequestParam long id){
fruitService.sellFruit(id);
}
@GetMapping("/fruit")
public Map<String, Long> getFruit(@RequestParam String name){
return fruitService.findFruit(name);
}
}
package com.group.libraryapp.dto;
import java.time.LocalDate;
public class FruitRequest {
private final String name;
private final LocalDate warehousingDate;
private final long price;
public FruitRequest(String name, LocalDate warehousingDate, long price) {
this.name = name;
this.warehousingDate = warehousingDate;
this.price = price;
}
public String getName() {
return name;
}
public LocalDate warehousingDate() {
return warehousingDate;
}
public long getPrice() {
return price;
}
}
package com.group.libraryapp.service;
import com.group.libraryapp.dto.FruitRequest;
import com.group.libraryapp.repository.FruitRepositroy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class FruitService {
private final FruitRepositroy fruitRepositroy;
public FruitService(JdbcTemplate jdbcTemplate) {
fruitRepositroy = new FruitRepositroy(jdbcTemplate);
}
public void saveFruit(FruitRequest request){
fruitRepositroy.saveFruit(request.getName(), request.warehousingDate(), request.getPrice());
}
public void sellFruit(long id){
if (fruitRepositroy.isExistFruit(id)){
throw new IllegalArgumentException();
}
fruitRepositroy.sellFruit(id);
}
public Map<String, Long> findFruit(String name){
long salesAmount = fruitRepositroy.calculateSalesAmount(name);
long notSalesAmount = fruitRepositroy.calculateNotSalesAmount(name);
Map<String, Long> response = new HashMap<>();
response.put("salesAmount", salesAmount);
response.put("notSalesAmount", notSalesAmount);
return response;
}
}
package com.group.libraryapp.repository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.time.LocalDate;
@Repository
public class FruitRepositroy {
JdbcTemplate jdbcTemplate;
public FruitRepositroy(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public boolean isExistFruit(long id){
String readSql = "SELECT * FROM fruit WHERE id = ?";
return jdbcTemplate.query(readSql, (rs, rowNum) -> 0, id).isEmpty();
}
public void saveFruit(String name, LocalDate warehousingDate, long price){
String sql = "INSERT INTO fruit (name, warehousingDate, price) VALUES (?, ?, ?)";
jdbcTemplate.update(sql, name, warehousingDate, price);
}
public void sellFruit(long id){
String sql = "UPDATE fruit set is_sale = false where id = ?";
jdbcTemplate.update(sql, id);
}
public long calculateSalesAmount(String name) {
String sql = "SELECT SUM(price) FROM fruit WHERE name = ? AND is_sale = true";
return jdbcTemplate.queryForObject(sql, new Object[]{name}, Long.class);
}
public long calculateNotSalesAmount(String name) {
String sql = "SELECT SUM(price) FROM fruit WHERE name = ? AND is_sale = false";
return jdbcTemplate.queryForObject(sql, new Object[]{name}, Long.class);
}
}
3일차 과제 [인프런 워밍업 클럽 스터디 BE 1주차]