본문 바로가기
💻 뚝딱뚝딱/팀내도서대여시스템(OBRS)

[개발일지#015] 대여내역 조회하기 (+ 썸네일 추가)

by 뚜루리 2025. 2. 20.
728x90
320x100

[개발목표]

  • 책 단건 조회시, 하단에 대여했던 내역을 확인 가능하게끔 구현
  • 책 단건 조회시, 책 이미지도 보여지게끔 구현

 


 

[구현화면]

책 정보

  • 책 단건조회 시, 하단에 대여 기록을 확인할 수 있도록 구현.

 


 

[구현하기]

bookMapper.xml

    <!-- 책 대여 기록 조회 -->
    <select id="findRentalHistoryByBookId" resultType="seulgi.bookRentalSystem.domain.book.BookRental">
        SELECT
            ROW_NUMBER() OVER (ORDER BY RENTAL_DATE DESC) AS row_num,
                BOOK_RENTAL_ID,
            (SELECT MEMBER_NAME FROM MEMBER_TB WHERE MEMBER_ID = BOOK_RENTAL_ID) AS BOOK_RENTAL_NAME,
            RENTAL_DATE,
            RETURN_DATE
        FROM BOOK_RENTAL
        WHERE BOOK_ID = #{bookId}
        ORDER BY RENTAL_DATE DESC;
    </select>

 

bookMapper.java

package seulgi.bookRentalSystem.domain.book;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface BookMapper {

    //생략
    
    //책 대여 기록 조회
    List<BookRental> findRentalHistoryByBookId(@Param("bookId") String bookId);

	//생략

}

 

 

bookServiceImpl.java

package seulgi.bookRentalSystem.domain.book;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class BookServiceImpl implements BookService {

    private final BookMapper bookMapper;

    //생략

    //책 대여 기록 조회
    @Override
    public List<BookRental> findRentalHistoryByBookId(String bookId) {
        return bookMapper.findRentalHistoryByBookId(bookId);
    }
	
    //생략

}

 

 

BookController.java

package seulgi.bookRentalSystem.web.book;

import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import seulgi.bookRentalSystem.domain.book.*;
import seulgi.bookRentalSystem.domain.member.Member;
import seulgi.bookRentalSystem.domain.member.MemberServiceImpl;
import seulgi.bookRentalSystem.domain.member.UpdateForm;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Controller
@RequiredArgsConstructor
@Transactional
@RequestMapping("/book")
public class BookController {

    private final BookServiceImpl bookService;

    
    /**
     * 책 단건 조회
     * @param bookId
     * @param model
     * @param request
     * @return
     */
    @GetMapping("/{bookId}")
    public String book(@PathVariable String bookId, Model model
    ,HttpServletRequest request){
        String loginId = (String) request.getSession().getAttribute("loginId");
        String rentalId = bookService.findRentalIdByBookId(bookId);
        Book book = bookService.findByBookId(bookId);
        book.setAuthorName(book.getAuthorName());
        book.setBookRentalId(rentalId);
        // 📌 대여 이력 추가
        List<BookRental> rentalHistory = bookService.findRentalHistoryByBookId(bookId);


        model.addAttribute("loginId", loginId);
        model.addAttribute("book", book);
        model.addAttribute("rentalHistory", rentalHistory); // 📌 대여 기록 모델 추가
        return "book/book";
    }

  
}

 

 

book.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{common/layout}"
      layout:fragment="content">
<head>
  <title>책 정보</title>
  <script th:src="@{/js/book/book.js}"></script>
</head>
<body>
<div class="container" style="max-width: 800px">

  <div class="py-5 text-center">
    <h2>책 정보</h2>
  </div>

  //생략
  
  <!-- 책 썸네일 -->
  <div class="mb-3 d-flex justify-content-center">
    <img id="bookImage" th:if="${book.thumbnailImg != null and book.thumbnailImg != ''}"
         th:src="${book.thumbnailImg}" alt="책 이미지"
         style="width: 200px; height: auto; border-radius: 10px;">
  </div>
  
  //생략
  
  <div style="margin-top: 80px;">
    <hr class="my-4">
    <!-- 대여 기록 있을 때 -->
    <h3>대여 기록</h3>
    <table class="table" th:if="${not #lists.isEmpty(rentalHistory)}">
      <thead>
      <tr>
        <th>No</th>
        <th>대여한 사람 ID</th>
        <th>대여 시간</th>
        <th>반납 시간</th>
      </tr>
      </thead>
      <tbody>
      <tr th:each="rental, stat : ${rentalHistory}">
        <td th:text="${stat.count}">1</td>
        <td th:text="${rental.bookRentalName}">사용자</td>
        <td th:text="${rental.rentalDate}">2025-02-19 14:00</td>
        <td th:text="${rental.returnDate != null ? rental.returnDate : '대여 중'}">대여 중</td>
      </tr>
      </tbody>
    </table>

    <!-- 대여 기록 없을 때 -->
    <p class="text-center text-muted" th:if="${#lists.isEmpty(rentalHistory)}">대여 기록이 없습니다.</p>

  </div>
</div>
</body>
</html>
  • 대여 기록이 없을 땐 대여기록이 없습니다 라고 띄움.

 

book.js

document.addEventListener('DOMContentLoaded', function (){
    
    //생략

    // 책 이미지 표시 여부 설정
    const bookImage = document.getElementById("bookImage");
    // 이미지 URL이 잘못된 경우 숨김
    if (!bookImage.src || bookImage.src.includes("/book/BOOK")) {
        bookImage.style.display = "none";
    } else {
        bookImage.style.display = "block";
    }

})
  • 저장된 책 이미지 경로가 없을 땐 빈 화면, 보일 때만 이미지 보이게끔 구현. 
728x90
320x100

뚜루리님의
글이 좋았다면 응원을 보내주세요!