드디어 늘 경계하는 부분에 도전~
레코드 건수가 수천, 수만이 아닌 수십개로 초간단한 버전으로 작업해봤다.
예전에 배웠던 것 참고하면서 chat gpt에게도 도움 받아서 부담감이 좀 덜했단가.
상품목록뿐 아니라 주문목록, 통계 등 다른 페이지에도 적용할 여지가 있어 공통사용될 패키지 만들고, 필요한 class를 여기서 생성했다.
Vo
package com.mall.common;
...
@Data
public class PaginationVo {
private int pageSize; // 한 페이지에 표시할 레코드 수
private int pageNumber; // 현재 페이지 번호
public int getOffset() {
return (pageNumber - 1) * pageSize;
}
}
Mapper
//전체 리스트
@Select("SELECT * FROM products "
+ "ORDER BY product_code DESC "
+ "LIMIT #{pageSize} OFFSET #{offset}")
List<PrdVo> prdList(@Param("pageSize") int pageSize,
@Param("offset") int offset);
//페이지 분리 위한 총상품수 계산
@Select("SELECT count(*)"
+ " FROM products")
int totalCount();
Service
public List<PrdVo> prdList(int pageSize, int pageNumber) {
PaginationVo pagination = new PaginationVo();
pagination.setPageSize(pageSize);
pagination.setPageNumber(pageNumber);
int offset = pagination.getOffset();
return prdMapper.prdList(pageSize, offset);
}
//페이지 분리 위한 총상품수 계산
public int totalCount() {
return prdMapper.totalCount();
}
위 메서드 한 세트로 관리자용 상품목록 & 전체상품 애너테이션에 공통적으로 사용했다.
pageSize만 페이지 구조 특정에 따라 바꿨다.
아래는 관리자용 상품목록 조회 시의 애너테이션이다.
Ctrl
@GetMapping("prdList") //상품 리스트 관리
public String prdList(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
Model model) {
System.out.println("prdList");
int pageSize = 10;
List<PrdVo> li=prdSvc.prdList(pageSize, pageNumber);
model.addAttribute("li", li);
model.addAttribute("lisize", li.size()); //현재 보고있는 페이지의 건수
model.addAttribute("pageSize", pageSize); //페이지당 건수
model.addAttribute("currentPage", pageNumber); //현재 페이지 번호
int totalRecords = prdSvc.totalCount(); //전체 건수
int totalPages = (int) Math.ceil(totalRecords * 1.0 / pageSize); //전체 페이지 개수
model.addAttribute("totalPages", totalPages);
model.addAttribute("totalRecords", totalRecords);
...
return "prd/prdList";
}
Front
<div th:text="${lisize} + ' / ' + ${totalRecords} + '건이 표시됩니다.'"></div>
<div th:if="${totalPages > 1}"
style="width: 100%; display: flex; flex-wrap: wrap; justify-content: center;
margin-top:10px; margin-bottom: 20px">
<a th:if="${currentPage !=1}"
th:href="@{/prd/prdList(pageNumber=1)}"
th:text="'[첫 페이지]'"></a> 
<div th:each="i : ${#numbers.sequence(((currentPage - 1) / 10) * 10 + 1, totalPages)}">
<div th:if="${i >= ((currentPage - 1) / 10) * 10 + 1 && i <= totalPages}">
<!-- 현재 페이지인 경우 비활성화 -->
<span th:if="${i == currentPage}"
th:text="'[' + ${i} + ']'"
style="color: gray; cursor: default; font-weight: bold;"></span>
<!-- 현재 페이지가 아닌 경우 링크 활성화 -->
<a th:if="${i != currentPage}"
th:href="@{/prd/prdList(pageNumber=${i})}"
th:text="'[' + ${i} + ']'"></a> 
</div>
</div>
<a th:if="${currentPage !=totalPages}"
th:href="@{/prd/prdList(pageNumber=${totalPages})}"
th:text="'[마지막 페이지]'"></a> 
</div>
사용자 위한 전체목록: