게시글의 목록에서 제목을 누르면 상세보기가 되고 목록이 10개가 넘어가면 페이지가 넘어가도록 구현해보았다.
Rest로 JSON써서 해볼까? 했는데 어차피 간단하게 구현만 할거라 그냥 기본적으로 구현했다
@Controller
@RequiredArgsConstructor
@RequestMapping("/product")
public class ProductController {
...
@GetMapping("/detail/{productId}")
public String productDetail(@PathVariable Long productId, Model model){
ProductDTO productDTO = productService.findProductById(productId);
model.addAttribute("productDetail", productDTO);
return "product/detailForm";
}
기본적인 방법으로 사용
public class ProductServiceImpl implements ProductService{
@Override
public ProductDTO findProductById(Long productId){
Product product = productRepository.findById(productId)
.orElseThrow(() -> new RuntimeException("해당 아이디에 해당하는 상품을 찾을 수 없습니다."));
return convertToProductDTO(product);
}
...
private ProductDTO convertToProductDTO(Product product) {
return ProductDTO.builder()
.id(product.getId())
.productName(product.getProductName())
.category(product.getCategory())
.writerName(product.getWriterName())
.price(product.getPrice())
.createdDate(product.getCreatedDate())
.description(product.getDescription())
.imageUrls(product.getImageUrls())
.build();
}
Optinal로 감쌀까하다가 쉬운코드라 이대로 함
JPA의 Pageable
을 사용하여 페이징 구현 자세한 구현 방법은 따로 다룰생각
@Service
@RequiredArgsConstructor
public class ProductServiceImpl implements ProductService{
...
@Override
public Page<Product> findAllProduct(int page, int size) {
return productRepository.findAll(PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdDate")));
}
}
주요코드로는 findAll
과 of
인데
of(int page, int size, Sort sort) 으로 페이지 번호, 개수, 정렬관련 정보를 담아서 Page객체로 반환한다.
@GetMapping("/list")
public String productList(Model model,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
Page<Product> productPage = productService.findAllProduct(page, size);
List<Product> productList = productPage.getContent();
model.addAttribute("productList", productList);
model.addAttribute("currentPage", page);
model.addAttribute("totalPages", productPage.getTotalPages());
return "product/ListForm";
}
<div th:if="${totalPages > 1}">
<div>
<span th:if="${currentPage > 0}">
<a th:href="@{/product/list(page=0, size=${size})}">처음</a>
<a th:href="@{/product/list(page=${currentPage - 1}, size=${size})}">이전</a>
</span>
<span th:each="pageNum : ${#numbers.sequence(0, totalPages - 1)}" th:class="${pageNum == currentPage} ? 'active'">
<a th:href="@{/product/list(page=${pageNum}, size=${size})}" th:text="${pageNum + 1}">1</a>
</span>
<span th:if="${currentPage < totalPages - 1}">
<a th:href="@{/product/list(page=${currentPage + 1}, size=${size})}">다음</a>
<a th:href="@{/product/list(page=${totalPages - 1}, size=${size})}">마지막</a>
</span>
</div>
</div>