์ถ์ฒ
https://inf.run/XKQg
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํด ๋ง๋๋ API ๊ฐ์์์ JdbcTemplate์ ์ฌ์ฉํ์ฌ DB์ SQL๋ฌธ์ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ํ์ตํ๋ค.
JDBC(Java Database Connectivity)์ ํต์ฌ ๋ถ๋ถ์ ๋ด๋นํ๋ ์ค์ฌ ๋๋ฆฌ์์ด๋ค.
๊ฐ๋จํ ๋งํ๋ฉด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ๋์์ฃผ๋ ๋๊ตฌ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
create table fruit
(
id bigint auto_increment,
name varchar(20),
warehousingDate date,
price long,
is_sold boolean default 0,
primary key (id)
);
๋จผ์ , fruit
ํ
์ด๋ธ์ ์ด๋ค ์นผ๋ผ์ด ํ์ํ์ง ํ์ธํ๋ค.
๋ฌธ์ 1์ HTTP ์์ฒญ ๋ณธ๋ฌธ์์ name, warehosuingDate, price
๊ฐ ํ์ํ๊ณ , ๋ฌธ์ 2, ๋ฌธ์ 3์ ํด๊ฒฐํ๊ธฐ ์ํด ํด๋น ๊ณผ์ผ์ด ํ๋งค๋ ์ํ์ธ์ง๋ฅผ ๋ํ๋ด๋is_sold
๋ผ๋ ์นผ๋ผ์ ์ถ๊ฐํ๋ค.
๋ฐ์ดํฐ์ ํํ ๋ฒ์๋ฅผ ํ์ฅํ๊ธฐ ์ํด price
์นผ๋ผ์ ๋ฐ์ดํฐ ํ์
์ผ๋ก long
์ ์ ํํ๋ค.
๋ํ, is_sold
์นผ๋ผ์๋ default
๋ฅผ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ๊ฐ์ด 0์ด ๋๋๋ก ์ค์ ํ๋ค.
(๊ณผ์ผ์ด ํ๋งค๋์ง ์์ ์ํ์ผ ๋, ๋ณ๋์ ๊ฐ ์ง์ ์์ด 0์ด ์๋์ผ๋ก ํ ๋น๋์ด ์ง๊ด์ ์ด๊ณ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์๋ค.)
public record FruitInfoRequest(String name, LocalDate warehousingDate, long price) {
}
@RestController
@RequiredArgsConstructor
public class FruitController {
private final JdbcTemplate jdbcTemplate;
@PostMapping("/api/v1/fruit")
public void saveFruit(@RequestBody FruitInfoRequest request) {
String sql = "insert into fruit (name, warehousingDate, price) values (?, ?, ?)";
jdbcTemplate.update(sql, request.name(), request.warehousingDate(), request.price());
}
}
HTTP POST ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ก, /api/v1/fruit
์๋ํฌ์ธํธ์ ๋งคํ๋์ด ์๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์ ์กํ HTTP ์์ฒญ์ ๋ณธ๋ฌธ(@RequestBody FruitInfoRequest request)์์ ๋ฐ์ ๊ณผ์ผ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ 'fruit' ํ
์ด๋ธ์ ์ ์ฅํ๋ค.
๋ฉ์๋ ๋ด๋ถ์์๋ SQL ์ฟผ๋ฆฌ๋ฅผ ์ ์ํ๊ณ , JdbcTemplate์ update ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ค.
์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ก์ด ๊ณผ์ผ ์ ๋ณด๊ฐ ์
๋ ฅ๋๋ฉฐ, SQL ์ฟผ๋ฆฌ์์๋ name, warehousingDate, price ๊ฐ์ด FruitInfoRequest ๊ฐ์ฒด์์ ๊ฐ์ ธ์จ ๊ฐ์ผ๋ก ๋์ฒด๋๋ค.
public record FruitIdRequest(long id) {}
@RestController
@RequiredArgsConstructor
public class FruitController {
private final JdbcTemplate jdbcTemplate;
@PutMapping("/api/v1/fruit")
public void updateFruit(@RequestBody FruitIdRequest request) {
String readSql = "select * from fruit where id = ?";
boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.id()).isEmpty();
if (isFruitNotExist) {
throw new IllegalArgumentException("ํด๋นํ๋ ๊ณผ์ผ์ด ์กด์ฌํ์ง ์์ต๋๋ค.");
}
String sql = "update fruit set is_sold = 1 where id = ?";
jdbcTemplate.update(sql, request.id());
}
}
HTTP PUT ์์ฒญ์ ์ฒ๋ฆฌํ๋ updateFruit ๋ฉ์๋๋ก,/api/v1/fruit
์๋ํฌ์ธํธ์ ๋งคํ๋์ด ์๋ค.
ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ FruitIdRequest ๊ฐ์ฒด๋ฅผ ํตํด ํน์ ๊ณผ์ผ์ ID๋ฅผ ๊ฐ์ ธ์จ๋ค.
ํด๋น ID๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ 'fruit' ํ
์ด๋ธ์ ์กฐํํ๋ SQL ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ค.
๋ง์ฝ ์กฐํ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด (= isEmpty()
๊ฐ true
๋ผ๋ฉด), ํด๋นํ๋ ID์ ๊ณผ์ผ์ด ์กด์ฌํ์ง ์๋๋ค๋ ์์ธ๋ฅผ ๋์ง๋ค.
์กฐํ ๊ฒฐ๊ณผ๊ฐ ์๋ค๋ฉด, ํด๋นํ๋ ID์ ๊ณผ์ผ์ 'fruit' ํ
์ด๋ธ์์ ์ฐพ์ is_sold
์นผ๋ผ์ 1๋ก ์
๋ฐ์ดํธํ์ฌ ํด๋น ๊ณผ์ผ์ ํ๋งค๋ ์ํ๋ก ๋ณ๊ฒฝํ๋ค.
public record FruitAmountResponse(long salesAmount, long notSalesAmount) {
}
@RestController
@RequiredArgsConstructor
public class FruitController {
private final JdbcTemplate jdbcTemplate;
@GetMapping("/api/v1/fruit/stat")
public FruitAmountResponse getAmount(@RequestParam String name) {
String readSql = "select * from fruit where name = ?";
boolean isFruitNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, name).isEmpty();
if (isFruitNotExist) {
throw new IllegalArgumentException("ํด๋นํ๋ ๊ณผ์ผ์ด ์กด์ฌํ์ง ์์ต๋๋ค.");
}
String sql1 = "select sum(price) as salesAmount from fruit where is_sold = 1";
String sql2 = "select sum(price) as notSalesAmount from fruit where is_sold = 0";
Long salesAmount = jdbcTemplate.queryForObject(sql1, (rs, rowNum) -> rs.getLong("salesAmount"));
Long notSalesAmount = jdbcTemplate.queryForObject(sql2, (rs, rowNum) -> rs.getLong("notSalesAmount"));
return new FruitAmountResponse(salesAmount, notSalesAmount);
}
}
HTTP GET ์์ฒญ์ ์ฒ๋ฆฌํ๋ getAmount ๋ฉ์๋๋ก, /api/v1/fruit/stat
์๋ํฌ์ธํธ์ ๋งคํ๋์ด ์๋ค.
ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ๊ณผ์ผ์ ์ด๋ฆ(@RequestParam String name)์ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค์ 'fruit' ํ
์ด๋ธ์ ์กฐํํ๋ค.
๋ฌธ์ 2์ฒ๋ผ ๊ณผ์ผ์ด ์กด์ฌํ์ง ์์ผ๋ฉด ์์ธ๋ฅผ ๋์ ธ ๊ฒ์ฆํ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ณผ์ผ์ด ์กด์ฌํ๋ค๋ฉด, is_sold
๊ฐ 1(ํ๋งค๋ ์ํ)์ธ ๊ณผ์ผ์ ๊ฐ๊ฒฉ ํฉ๊ณ๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ(sql1)์ is_sold
๊ฐ 0(๋ฏธํ๋งค ์ํ)์ธ ๊ณผ์ผ์ ๊ฐ๊ฒฉ ํฉ๊ณ๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ(sql2)๋ฅผ ์คํํ์ฌ ํ๋ฆฐ ๊ธ์ก๊ณผ ํ๋ฆฌ์ง ์์ ๊ธ์ก์ ์กฐํํ๊ณ , ์ด๋ฅผ ์๋ต์ผ๋ก ๋ฐํํ๋ค.
๐ ์ฐธ๊ณ ์๋ฃ
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html