"상품 주문하기 버튼 코드"
<form id="BasketForm1" action="/fromBasketToOrders" method="GET">
<button id="Basket1" class="btn btn-primary btn-sm btn-fixed-width"
style="margin-right: 10px; background-color: #7013F2; border-color: #7013F2; color: white;">
상품 주문하기
</button>
<input type="hidden" id="BasketId1" name="isbn" th:value="${book.isbn}">
</form>
"/fromBasketToOrders"라는 @GetMapping 메서드를 실행 해 상품을 주문하는데 이 때 해당 책의 isbn을 넘겨준다,.
BasketController
@GetMapping("/fromBasketToOrders")
public String FromBasketToOrderBook(@RequestParam("isbn") String isbn) {
log.info("FromBasketToOrderBook");
try {
orderBookService.processOrderBook(isbn);
return "redirect:/home";
} catch (NoSuchElementException | DuplicateOrderException | IllegalStateException e) {
log.error(e.getMessage(), e);
throw e;
}
}
OrderBookService - processOrderBook 메서드
@Transactional
public void processOrderBook(String isbn) {
Book book = bookRepository.findByIsbn(isbn);
log.info("book.isbn = {}", book.getIsbn());
if (book == null) {
throw new NoSuchElementException("ISBN에 해당하는 책이 존재하지 않습니다.");
}
OrderBook orderBook = getOrderBook(book);
if (orderBookRepository.findByIsbn(isbn) != null) {
throw new DuplicateOrderException("이미 주문하기 화면에 해당 상품이 존재합니다.");
}
try {
saveOrderBook(orderBook);
bookService.deleteBook(book.getIsbn());
} catch (Exception e) {
log.error("주문 저장을 실패하였습니다");
throw new IllegalStateException(e.getMessage());
}
}
isbn으로 책을 book db(장바구니 db)에서 찾은 뒤,
책이 존재하면, orderbook에 기존 book을 매핑해주고 저장(orderBook db (주문하기 db))
책이 존재하지 않으면 예외를 던져줌
두 가지 짚고 넘어갈 점
1. html에서 isbn을 넘겨줄 때(th:value="${book.isbn}) controller에서는 "@RequestParam"으로 받아준다.
2. isbn으로 넘어가는 값은 em.find를 통해 조회하지 못한다!
처음에는 em.find(isbn, Book.class) 이런식으로 조회하려고 했지만, em.find 자체가 pk기준으로 조회하는 것이기 때문에 이렇게
아예 코드를 짜줘야 함 pk로 값을 조회하는거 아니면.
이제 장바구니에서 상품 주문하기 버튼 클릭시 홈 화면으로 들어가면서 DB에 들어가게 될 것이다.
DB 연동 확인
@GetMapping("home/mypage/orderBooks")
public String OrderBookPage(Model model) {
log.info("주문하기 화면으로 이동합니다.");
List<OrderBook> orderBooks = orderBookRepository.orderBookList();
log.info("orderBooks={}", orderBooks);
int totalOrderAmount = orderBookService.calculateTotalOrderAmount(orderBooks);
if (orderBooks != null && !orderBooks.isEmpty()) {
model.addAttribute("orderBooks", orderBooks);
model.addAttribute("totalOrderAmount", totalOrderAmount);
return "home/mypage/orders";
} else {
throw new OrderBooknotFoundException("장바구니에 상품이 존재하지 않습니다.");
}
}
orderBookRepository.orderBookList();
public List<OrderBook> orderBookList() {
return em.createQuery("select ob from OrderBook ob", OrderBook.class).getResultList();
}
orderBookList를 통해 orderBookRepository db에 있는 값들을 List형식으로 가져와서 model에 orderBooks 이름으로 넘긴 뒤,
html에서
<tr>
<th>ISBN</th>
<th>이미지</th>
<th>제목</th>
<th>저자/출판사</th>
<th>출판일</th>
<th>discount</th>
<th>기타</th>
</tr>
</thead>
<!-- 수정 후 코드 -->
<tr th:each="orderbook:${orderBooks}">
<td>[[${orderbook.isbn}]]</td>
<td><img th:src="${orderbook.image}" th:alt="${orderbook.name}" width="100"></td>
<td><a th:href="${orderbook.link}">[[${orderbook.name}]]</a></td>
<td>[[${orderbook.author}]]/[[${orderbook.publisher}]]</td>
<td>[[${orderbook.pubdate}]]</td>
<td>[[${orderbook.stockQuantity}]]</td>
이런식으로 가져와서 타임리프를 사용하기만 하면
상품 주문 화면에 상품 등록되는 거 확인하면 끝!
basket.html
<form id="BasketForm2" action="/FromBasketToWishlist" method="GET">
<button id="Basket2" class="btn btn-primary btn-sm btn-fixed-width"
style="margin-right: 10px; background-color: #F26B6B; border-color: #F26B6B; color: white;">
찜 목록에 추가하기
</button>
<input type="hidden" id="BasketId2" name="isbn" th:value="${book.isbn}">
</form>
BasketController
@GetMapping("/FromBasketToWishlist")
//isbn와 찜 목록 버튼을 통해 값 보내주기
public String FromBasketToWishlist(@RequestParam("isbn") String isbn) {
try {
log.info("wishlistFromISBN");
wishlistService.addFromBasketToWishlist(isbn);
//성공적으로 저장 되었음 -> 홈 화면으로 리다이렉션
return "redirect:/home";
} catch (Exception e) {
// Wishlist 저장 실패 또는 다른 예외 발생 시 처리
log.error("해당 상품이 이미 찜 목록에 존재합니다 : {}", e.getMessage());
throw new IllegalStateException("해당 상품이 이미 찜 목록에 존재합니다.");
}
}
WishlistService - addFromBasketToWishlist
@Transactional
public void addFromBasketToWishlist(String isbn) {
Book book = bookRepository.findByIsbn(isbn);
log.info("book = {}", book);
//책이 존재하지 않을 경우 예외 처리
if (book == null) {
log.error("해당 책이 존재하지 않습니다.");
throw new EntityNotFoundException("해당 책이 존재하지 않습니다");
}
//찜 목록에 해당 책이 이미 존재하는지 확인
Wishlist wishlistByIsbn = wishlistRepository.findByIsbn(book.getIsbn());
if (wishlistByIsbn != null) {
log.error("해당 책이 이미 찜 목록에 존재합니다.");
throw new DuplicateIsbnException("이미 찜 목록에 해당 상품이 존재합니다.");
}
Wishlist wishlistBook = convertToEntityWishlistBook(book);
log.info("wishlistBook = {}", wishlistBook);
wishlistRepository.save(wishlistBook);
}
해당 책이 존재하면 wishlist 형태의 book(wishlistBook)으로 변환 후 wishlist db에 값 저장
예외 시, 예외 던져준 (던져준 예외는 GlobalExceptionHandler로 잡아줌)
찜 목록에 잘 추가되었으면 성공!
삭제된 거를 보기 위해 먼저 2개를 DB에 넣어놓았음
1) 먼저 html에서 상품 취소하기 버튼 클릭시 isbn을 파라미터로 넘겨줘야 함
<form id="BasketForm3" action="/delete_book" method="GET">
<button id="Basket3" class="btn btn-primary btn-sm btn-fixed-width" style="margin-right: 10px; background-color: #3F88C5; border-color: #3F88C5; color: white;">상품 취소하기</button>
<input type="hidden" id="BasketId3" name="isbn" th:value="${book.isbn}">
</form>
2) 그리고 controller에서 action과 method 값을 통해 구현
@GetMapping("/delete_book")
public String delete_book(@RequestParam("isbn") String isbn) {
bookService.deleteBook(isbn);
return "redirect:/home";
}
서비스 계층에서 비즈니스 로직을 처리하기 때문에 controller에서는 @RequestParam으로 받은 isbn을 서비스 계층으로 넘겨서 처리하도록 함
3) bookService
public void deleteBook(String isbn) {
log.info("deleteBook - isbn = {}", isbn);
Book book = bookRepository.findByIsbn(isbn);
log.info("book.isbn = {}", book.getIsbn());
//책이 존재하면
if (book != null) {
bookRepository.deleteByIsbn(book.getIsbn());
log.info("Book with ISBN {} deleted successfully", isbn);
} else {
log.error("상품이 존재하지 않습니다. isbn = {}", isbn);
throw new EntityNotFoundException("상품이 존재하지 않습니다. isbn = {}" + isbn);
}
}
넘겨온 isbn으로 책을 찾고
책이 존재할 때 bookRepository.deleteByIsbn 메서드를 통해 지우고,
책이 없다면 예외를 터트린다.
4) bookRepository
public interface BookRepository extends JpaRepository<Book, Long> {
Book findByIsbn(String isbn);
void deleteByIsbn(String isbn);
}
db에서 값을 지워줘야 하니까 Service 계층에서 Repository 계층으로 이동해 삭제 처리 해준다.
이제 버튼을 누르면
삭제 후
db에도 값이 지워지는 거 확인!