728x90
[문제 상황]
서로 다른 2개의 테이블을 페이징 하였으나 서로 페이지 번호가 동기화 되어 움직인다.
"비완료 과업" 테이블의 페이지를 변경했지만, "비완료 과업" 과 "완료 과업" 테이블의 페이지가 동시에 같은 페이지로 이동되는 문제가 발생하였다.
[문제 원인]
1. "finishedTaskList" 와 "unfinishedTaskList" 가 같은 "Pageable" 사용
/**
* member Information ("/members/info")
*/
@GetMapping("/info")
public String memberInformation(@PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
Model model) {
/**
* 회원 정보
*/
Member currentMember = getCurrentMember();
MemberResponseDto responseDto = new MemberResponseDto(currentMember);
model.addAttribute("responseDto", responseDto);
//현재 로그인된 Username - header 에 명시
model.addAttribute("signedMember", memberService.getCurrentUsername());
/**
* finishedTaskList
*/
Page<Task> tasks1 = taskService.getIsCheckedTaskList(currentMember, true, pageable);
Page<TaskResponseDto> finishedTaskList = tasks1.map(TaskResponseDto::new);
model.addAttribute("finishedTaskList", finishedTaskList);
model.addAttribute("previous1", pageable.previousOrFirst().getPageNumber()); //이전 페이지 정보
model.addAttribute("next1", pageable.next().getPageNumber()); //다음 페이지 정보
model.addAttribute("hasPrevious1", finishedTaskList.hasPrevious()); //이전 페이지 존재 여부
model.addAttribute("hasNext1", finishedTaskList.hasNext()); //다음 페이지 존재 여부
//페이지 번호
int currentPage1 = pageable.getPageNumber() + 1; //현재 페이지 정보(User side)
model.addAttribute("current1", currentPage1);
int blockSize1 = 5;
int startPage1 = ((currentPage1 - 1) / blockSize1) * blockSize1 + 1; //블럭 시작 페이지
int endPage1 = Math.min(startPage1 + blockSize1 - 1, finishedTaskList.getTotalPages()); //블럭 마지막 페이지
model.addAttribute("startPage1", startPage1);
model.addAttribute("endPage1", endPage1);
/**
* unfinishedTaskList
*/
Page<Task> tasks2 = taskService.getIsCheckedTaskList(currentMember, false, pageable);
Page<TaskResponseDto> unfinishedTaskList = tasks2.map(TaskResponseDto::new);
model.addAttribute("unfinishedTaskList", unfinishedTaskList);
model.addAttribute("previous2", pageable.previousOrFirst().getPageNumber()); //이전 페이지 정보
model.addAttribute("next2", pageable.next().getPageNumber()); //다음 페이지 정보
model.addAttribute("hasPrevious2", unfinishedTaskList.hasPrevious()); //이전 페이지 존재 여부
model.addAttribute("hasNext2", unfinishedTaskList.hasNext()); //다음 페이지 존재 여부
//페이지 번호
int currentPage2 = pageable.getPageNumber() + 1; //현재 페이지 정보(User side)
model.addAttribute("current2", currentPage2);
int blockSize2 = 5;
int startPage2 = ((currentPage2 - 1) / blockSize2) * blockSize2 + 1; //블럭 시작 페이지
int endPage2 = Math.min(startPage2 + blockSize2 - 1, unfinishedTaskList.getTotalPages()); //블럭 마지막 페이지
model.addAttribute("startPage2", startPage2);
model.addAttribute("endPage2", endPage2);
// 달성 Task 수 / 미달성 Task 수
model.addAttribute("checkTaskNum", taskService.checkTaskNum(currentMember, true));
model.addAttribute("totalTaskNum", taskService.checkTaskNum(currentMember, false));
return "members/info";
}
"finishedTaskList" 와 "unfinishedTaskList" 가 같은 "Pageable" 을 사용하기 때문에 문제가 발생하였다.
2. "finishedTaskList" 와 "unfinishedTaskList" 가 서로 다른 독립적인 "Pageable" 사용
// Pageable 수정
Pageable finishedPageable = PageRequest.of(finishedPage, pageable.getPageSize(), pageable.getSort());
Pageable unfinishedPageable = PageRequest.of(unfinishedPage, pageable.getPageSize(), pageable.getSort());
"finishedTaskList" 와 "unfinishedTaskList" 의 Pageable 을 분리한다.
[MemberController.class 中...]
/**
* member Information ("/members/info")
*/
@GetMapping("/info")
public String memberInformation(@RequestParam(value = "finishedPage", defaultValue = "0") int finishedPage,
@RequestParam(value = "unfinishedPage", defaultValue = "0") int unfinishedPage,
@PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
Model model) {
/**
* 회원 정보
*/
Member currentMember = getCurrentMember();
MemberResponseDto responseDto = new MemberResponseDto(currentMember);
model.addAttribute("responseDto", responseDto);
//현재 로그인된 Username - header 에 명시
model.addAttribute("signedMember", memberService.getCurrentUsername());
// Pageable 수정
Pageable finishedPageable = PageRequest.of(finishedPage, pageable.getPageSize(), pageable.getSort());
Pageable unfinishedPageable = PageRequest.of(unfinishedPage, pageable.getPageSize(), pageable.getSort());
/**
* finishedTaskList
*/
Page<Task> tasks1 = taskService.getIsCheckedTaskList(currentMember, true, finishedPageable);
Page<TaskResponseDto> finishedTaskList = tasks1.map(TaskResponseDto::new);
model.addAttribute("finishedTaskList", finishedTaskList);
model.addAttribute("previous1", finishedPageable.previousOrFirst().getPageNumber()); //이전 페이지 정보
model.addAttribute("next1", finishedPageable.next().getPageNumber()); //다음 페이지 정보
model.addAttribute("hasPrevious1", finishedTaskList.hasPrevious()); //이전 페이지 존재 여부
model.addAttribute("hasNext1", finishedTaskList.hasNext()); //다음 페이지 존재 여부
//페이지 번호
int currentPage1 = finishedPageable.getPageNumber() + 1; //현재 페이지 정보(User side)
model.addAttribute("current1", currentPage1);
int blockSize1 = 5;
int startPage1 = ((currentPage1 - 1) / blockSize1) * blockSize1 + 1; //블럭 시작 페이지
int endPage1 = Math.min(startPage1 + blockSize1 - 1, finishedTaskList.getTotalPages()); //블럭 마지막 페이지
model.addAttribute("startPage1", startPage1);
model.addAttribute("endPage1", endPage1);
/**
* unfinishedTaskList
*/
Page<Task> tasks2 = taskService.getIsCheckedTaskList(currentMember, false, unfinishedPageable);
Page<TaskResponseDto> unfinishedTaskList = tasks2.map(TaskResponseDto::new);
model.addAttribute("unfinishedTaskList", unfinishedTaskList);
model.addAttribute("previous2", unfinishedPageable.previousOrFirst().getPageNumber()); //이전 페이지 정보
model.addAttribute("next2", unfinishedPageable.next().getPageNumber()); //다음 페이지 정보
model.addAttribute("hasPrevious2", unfinishedTaskList.hasPrevious()); //이전 페이지 존재 여부
model.addAttribute("hasNext2", unfinishedTaskList.hasNext()); //다음 페이지 존재 여부
//페이지 번호
int currentPage2 = unfinishedPageable.getPageNumber() + 1; //현재 페이지 정보(User side)
model.addAttribute("current2", currentPage2);
int blockSize2 = 5;
int startPage2 = ((currentPage2 - 1) / blockSize2) * blockSize2 + 1; //블럭 시작 페이지
int endPage2 = Math.min(startPage2 + blockSize2 - 1, unfinishedTaskList.getTotalPages()); //블럭 마지막 페이지
model.addAttribute("startPage2", startPage2);
model.addAttribute("endPage2", endPage2);
// 달성 Task 수 / 미달성 Task 수
model.addAttribute("checkTaskNum", taskService.checkTaskNum(currentMember, true));
model.addAttribute("totalTaskNum", taskService.checkTaskNum(currentMember, false));
return "members/info";
}
[info.html 中...]
<!--"finishedTaskList" pagination-->
<div class="pagination-box">
<ul class="pagination">
<li class="page-item">
<a th:if="${hasPrevious1}" th:href="@{/members/info(finishedPage=${previous1}, unfinishedPage=${current2 - 1})}"
role="button" class="page-link">이전</a>
<a th:if="${!hasPrevious1}" th:href="@{/members/info(finishedPage=${previous1}, unfinishedPage=${current2 - 1})}"
role="button" class="page-link disabled">이전</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(startPage1, endPage1)}"
th:classappend="${pageNum == current1} ? active : ''">
<a th:href="@{/members/info(finishedPage=${pageNum - 1}, unfinishedPage=${current2 - 1})}" th:text="${pageNum}"
role="button" class="page-link">페이지 번호</a>
</li>
<li class="page-item">
<a th:if="${hasNext1}" th:href="@{/members/info(finishedPage=${next1}, unfinishedPage=${current2 - 1})}"
role="button" class="page-link">다음</a>
<a th:if="${!hasNext1}" th:href="@{/members/info(finishedPage=${next1}, unfinishedPage=${current2 - 1})}"
role="button" class="page-link disabled">다음</a>
</li>
</ul>
</div>
<!--"unfinishedTaskList" pagination-->
<div class="pagination-box">
<ul class="pagination">
<li class="page-item">
<a th:if="${hasPrevious2}" th:href="@{/members/info(finishedPage=${current1 - 1}, unfinishedPage=${previous2})}"
role="button" class="page-link">이전</a>
<a th:if="${!hasPrevious2}" th:href="@{/members/info(finishedPage=${current1 - 1}, unfinishedPage=${previous2})}"
role="button" class="page-link disabled">이전</a>
</li>
<li class="page-item" th:each="pageNum : ${#numbers.sequence(startPage2, endPage2)}"
th:classappend="${pageNum == current2} ? active : ''">
<a th:href="@{/members/info(finishedPage=${current1 - 1}, unfinishedPage=${pageNum - 1})}" th:text="${pageNum}"
role="button" class="page-link">페이지 번호</a>
</li>
<li class="page-item">
<a th:if="${hasNext2}" th:href="@{/members/info(finishedPage=${current1 - 1}, unfinishedPage=${next2})}"
role="button" class="page-link">다음</a>
<a th:if="${!hasNext2}" th:href="@{/members/info(finishedPage=${current1 - 1}, unfinishedPage=${next2})}"
role="button" class="page-link disabled">다음</a>
</li>
</ul>
</div>
[완료 화면]
"finishedTaskList" 와 "unfinishedTaskList" 의 페이징이 서로 분리되어 작동하는 것을 확인할 수 있다.
728x90