main.html 타임리프로 DB 값 가져오기
Books 엔티티 안에 Transaction, Images 엔티티 넣어서 사용
BooksRepository- BooksService- UserViewController 순, 컨트롤러에서 Books 엔티티를 Attribute로 넣고, html 코드 안에서 가져와서 사용
Books.java 안에 Transaction.java, Images.java 클래스를 변수로 선언할 때, 해당 ERD의 관계를 확인하고(OneToOne, OneToMany 등) 해당 변수 위에 어노테이션을 넣어줘야 하고 (mappedBy = “키값 변수이름”)을 함께 넣어줘야 한다.
OneToMany 관계는 클래스를 리스트 형태로 넣어줘야 한다고 한다.
@OneToOne(mappedBy = "bookId")
private Transactions transactions;
**@OneToMany(mappedBy = "bookId")
private List<Images> images;**
출력 화면

<!DOCTYPE html>
<html lang="ko"
xmlns:th="<http://www.thymeleaf.org>">
<head>
<title>main</title>
<link rel="stylesheet" href="<https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css>">
<style>
.image-size img {
width: 300px;
height: 300px;
}
.figcaption-center {
text-align: center;
}
</style>
</head>
<body>
<header th:replace="~{/header/header :: headerFragment}"></header>
<div class="container-fluid">
<div class="row">
<!-- Sidebar -->
<header th:replace="~{/sidebar/sidebar :: sidebarFragment}"></header>
<!-- Main -->
<main role="main" class="col-md-9 col-lg-10 px-md-4" style="margin-left: 200px">
<!-- 검색창 추가 -->
<br>
<div class="input-group">
<div class="input-group-prepend">
<select class="custom-select rounded-pill" id="search-type">
<option value="title">통합검색</option>
<option value="title">제목</option>
<option value="author">작가</option>
<option value="publisher">출판사</option>
</select>
</div>
<input type="search" class="form-control rounded-pill" id="search-input" placeholder=" " aria-label="Search" aria-describedby="search-addon" />
<button type="button" class="btn btn-outline-primary rounded-pill" style="color: black; border-color: #E2ECE2; background-color: #E2ECE2;" onclick="performSearch()">검색</button>
</div>
<br>
<!-- 이미지 출력 폼 -->
<form>
<div class="form-row">
<div class="form-group col-md-4" th:each="book : ${Books}">
<div th:each="image : ${book.images}" class="image-size" style="text-align: center;">
<a th:href="@{/board/detail/{bookId}(bookId=${book.book_id})}">
<img th:src="${image.image_url}" th:alt="${book.title}" style="display: inline-block;">
</a>
</div>
<div style="margin-bottom: 10px;"></div>
<figcaption class="figcaption-center">
<a th:href="@{/board/detail/{bookId}(bookId=${book.book_id})}">
<span th:text="${book.title}"></span>
</a>
<div style="background-color: #E2ECE2; border: 1px solid #E2ECE2; border-radius: 20px; color: black; font-size: 14px; padding: 5px 10px; pointer-events: none; display: inline-block;">
<span th:text="${book.transactions.status}"></span>
</div>
</figcaption>
</div>
</div>
</form>
</main>
</div>
</div>
<footer th:replace="~{/footer/footer :: footerFragment}"></footer>
</body>
</html>
Controller에서 Books 엔티티를 사용하지 않고, BookDTO를 사용
Books 엔티티를 바로 사용하지 말고 DTO로 변환하여 사용해야지 좋다고 한다.
DTO 생성
Service에서 엔티티를 DTO로 변환 작업(메서드 생성)
public BookDTO convertToDTO(Books books) {
BookDTO bookDTO = new BookDTO();
bookDTO.setBook_id(books.getBook_id());
bookDTO.setBoards(books.getBoards());
bookDTO.setIsbn(books.getIsbn());
bookDTO.setTitle(books.getTitle());
bookDTO.setAuthor(books.getAuthor());
bookDTO.setPublisher(books.getPublisher());
bookDTO.setPubdate(books.getPubdate());
bookDTO.setDescription(books.getDescription());
bookDTO.setGrade(books.getGrade());
bookDTO.setTransactions(books.getTransactions());
bookDTO.setImages(books.getImages());
return bookDTO;
}
Controller에서 사용
// DTO 사용 전 메서드
@GetMapping("/")
public String mainhtml(Model model){
List<Books> books = bookService.findAll();
model.addAttribute("Books", books);
return "content/user/main";
}
// DTO 사용 후 메서드
@GetMapping("/")
public String mainhtml(Model model){
List<Books> books = bookService.findAll(); // Book 엔티티를 가져옴
**List<BookDTO> bookDTOs = new ArrayList<>();**
**for (Books book : books) {
bookDTOs.add(bookService.convertToDTO(book)); // 엔티티를 DTO로 변환
}**
model.addAttribute("Books", bookDTOs); // BookDTO 리스트를 모델에 추가
return "content/user/main";
}