https://velog.io/@kysth0707/3-NestJS%EB%A1%9C-api
에서 Nestjs => Spring Boot 한 것이다
Spring Boot
controller
ㄴBookController, RentalsController
repository
ㄴBookRepository, RentalsRepository,
service
ㄴBookService, RentalsService
꼴
BookController
// src/main/java/.../controller/BookController.java
package com.umc.week3springboot.controller;
import com.umc.week3springboot.service.BookService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController // 1. "나는 데이터를 JSON으로 서빙하는 API 카운터야!"
@RequestMapping("/books") // 2. 이 컨트롤러로 들어오는 요청의 기본 주소는 /books
@RequiredArgsConstructor
public class BookController {
// 주방장(Service)을 주입받아 카운터 옆에 대기시킵니다.
private final BookService bookService;
// 3. HTTP GET 방식으로 /books 요청이 들어왔을 때 이 메서드가 실행됩니다.
@GetMapping
public List<Map<String, Object>> getBooks() {
return bookService.getAllBooks();
}
@GetMapping("/category/{categoryID}")
public List<Map<String, Object>> findBooksByCategoryID(@PathVariable("categoryID") Long categoryID) {
return bookService.findBooksByCategoryID(categoryID);
}
@PostMapping
public String createBook(@RequestBody Map<String, Object> body){
bookService.createBook(body);
return "도서 등록이 완료되었습니다!";
}
}
Rentals Controller
package com.umc.week3springboot.controller;
import com.umc.week3springboot.service.RentalsService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/rentals")
@RequiredArgsConstructor
public class RentalsController {
private final RentalsService rentalsService;
@PostMapping
public String rentBook(@RequestBody Map<String, Object> body){
rentalsService.rentBook(body);
return "정상적으로 대여했습니다.";
}
@PatchMapping("/{rentalID}/return")
public String returnBook(@PathVariable("rentalID") Long rentalID) {
rentalsService.returnBook(rentalID);
return "정상적으로 반납했습니다.";
}
}
BookRepository
// src/main/java/.../repository/BookRepository.java
package com.umc.week3springboot.repository;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository // 스프링 컨테이너에 "나 창고지기 부품이야!"라고 등록
@RequiredArgsConstructor
public class BookRepository {
// 2단계에서 준비된 스프링의 DB 통신 도구(JdbcTemplate) 주입
private final JdbcTemplate jdbcTemplate;
public List<Map<String, Object>> findAll() {
String sql = "SELECT * FROM book";
// 쿼리를 실행하고 결과를 List<Map> 형태의 날것 데이터로 긁어옵니다.
// Map의 Key는 '컬럼명(title)', Value는 '실제 데이터(달빛 도서관)'가 됩니다.
return jdbcTemplate.queryForList(sql);
}
public List<Map<String, Object>> findBooksByCategoryID(Long categoryID) {
String sql = "SELECT * FROM book WHERE category_id = ?;";
return jdbcTemplate.queryForList(
sql,
categoryID
);
}
public void save(Map<String, Object> body){
// book_id는 AUTO_INCREMENT이므로 생략, is_available은 기본 true로 삽입
String sql = "INSERT INTO book (category_id, title, description, is_available) VALUES (?, ?, ?, true)";
// SQL 뒤에 파라미터를 차례대로 넘겨주면 ? 자리에 순서대로 안전하게 바인딩됩니다.
jdbcTemplate.update(
sql,
body.get("categoryId"),
body.get("title"),
body.get("description")
);
}
}
Rentals Repository
package com.umc.week3springboot.repository;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository
@RequiredArgsConstructor
public class RentalsRepository {
private final JdbcTemplate jdbcTemplate;
public void rentBook(Map<String, Object> body){
String sql = "INSERT INTO rental (user_id, book_id, rented_at, due_at) VALUES (?, ?, NOW(), DATE_ADD(NOW(), INTERVAL 7 DAY))";
jdbcTemplate.update(
sql,
body.get("userId"),
body.get("bookId")
);
}
public void returnBook(Long rentalID) {
String sql = "UPDATE rental SET returned_at = NOW() WHERE rental_id = ?";
jdbcTemplate.update(
sql,
rentalID
);
}
}
BookService
// src/main/java/.../service/BookService.java
package com.umc.week3springboot.service;
import com.umc.week3springboot.repository.BookRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service // 비즈니스 로직을 수행하는 메인 셰프 계층
@RequiredArgsConstructor
public class BookService {
// 창고지기(Repository)를 생성자 주입으로 데려옵니다.
private final BookRepository bookRepository;
public List<Map<String, Object>> getAllBooks() {
// 지금은 별도 가공 없이 창고지기가 가져온 도서 목록을 그대로 반환합니다.
return bookRepository.findAll();
}
public List<Map<String, Object>> findBooksByCategoryID(Long categoryID) {
return bookRepository.findBooksByCategoryID(categoryID);
}
// BookService.java에 추가
public void createBook(Map<String, Object> body){
bookRepository.save(body);
}
}
Rentals Service