728x90
320x100
목록을 출력하는 모든 화면에 페이지네이션을 적용해보자.
[개발목표]
1. 페이지네이션 적용하기
페이지네이션을 적용할 화면은 회원목록 / 모든책 / 나의책 / 빌린책 총 4개의 화면이 될텐데
모두 비슷한 형태로 사용되기 때문에 회원목록의 예만 올려볼 예정.
[구현화면]
- 맨 처음 / 이전 / 페이지 부분 / 다음 / 맨 끝 형태로 페이지 네이션을 구현한다.
- 현재 페이지에 대한 표시는 육안으로 알아 볼 수 있게끔 한다.
MemberMapper.xml 수정 / 추가
<select id="allMemberList" resultType="seulgi.bookRentalSystem.domain.member.Member">
SELECT
MEMBER_ID AS memberId
, MEMBER_NAME AS memberName
, PASSWORD
, JOIN_DATE AS joinDate
FROM MEMBER_TB
ORDER BY joinDate
LIMIT #{offset}, #{limit}
</select>
<select id="countMembers" resultType="int">
SELECT COUNT(*)
FROM MEMBER_TB
</select>
- allMemberList는 기존에 있던 쿼리인데 LIMIT #{offset}, #{limit} 만 추가해주었다.
- CountMembers의 쿼리의 경우 목록의 전체 카운트 수를 가져오는 쿼리를 하나 만들어주었다.
memberMapper.java
package seulgi.bookRentalSystem.domain.member;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Optional;
@Mapper
public interface MemberMapper {
List<Member> allMemberList(@Param("offset") int offset, @Param("limit") int limit);
int countMembers();
}
offset, limit의 파라미터가 쿼리에서 추가되었으니 mapper에서도 파라미터로 넘겨준다.
meberService, memberServiceImpl.java
package seulgi.bookRentalSystem.domain.member;
import org.apache.ibatis.annotations.Param;
import seulgi.bookRentalSystem.domain.book.Book;
import seulgi.bookRentalSystem.domain.book.BookRental;
import java.util.List;
public interface MemberService {
List<Member> allMemberList(int page, int size);
int countMembers();
}
package seulgi.bookRentalSystem.domain.member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import seulgi.bookRentalSystem.domain.book.Book;
import seulgi.bookRentalSystem.domain.book.BookRental;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService{
private final MemberMapper memberMapper;
@Override
public List<Member> allMemberList(int page, int size) {
int offset = (page - 1) * size;
return memberMapper.allMemberList(offset, size);
}
@Override
public int countMembers() {
return memberMapper.countMembers();
}
}
MemberController.java
package seulgi.bookRentalSystem.web.member;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
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.login.LoginForm;
import seulgi.bookRentalSystem.domain.login.LoginService;
import seulgi.bookRentalSystem.domain.member.Member;
import seulgi.bookRentalSystem.domain.member.MemberServiceImpl;
import seulgi.bookRentalSystem.domain.member.UpdateForm;
import seulgi.bookRentalSystem.web.login.SessionConst;
import java.util.List;
@Controller
@RequiredArgsConstructor
@RequestMapping("/member")
public class MemberController {
private final MemberServiceImpl memberService;
/**
* 회원 목록 조회
* @param model
* @return
*/
@GetMapping
public String allMemberList(Model model
, @RequestParam(defaultValue = "1") int page
, @RequestParam(defaultValue = "10") int size){
List<Member> members = memberService.allMemberList(page, size);
int totalMembers = memberService.countMembers();
int totalPages = (int) Math.ceil((double) totalMembers / size);
model.addAttribute("members", members);
model.addAttribute("currentPage", page);
model.addAttribute("totalPages", totalPages);
return "member/allMemberList";
}
}
- @RequestParam()을 통해 Page, size를 가져오는데 처음 로딩할 때는 1페이지임으로 defaultValue = '1'로 준다.
- 여기서 int page는 현재 페이지를 뜻하며 int size는 한페이지에 몇 개를 담는지에 대한 변수다.
- 전체 회원목록 수와 페이지수를 계산하여 model에 담아 넘겨준다.
allMemberList.html
<nav aria-label="Page navigation example"
th:fragment="pagenation">
<ul class="pagination" style="display: flex; justify-content: center;">
<li class="page-item" th:classappend="${currentPage > 1} ? '' : 'disabled'">
<a class="page-link" th:href="@{/member(page=1)}">First</a>
</li>
<li class="page-item" th:classappend="${currentPage > 1} ? '' : 'disabled'">
<a class="page-link" th:href="@{/member(page=${currentPage - 1})}">Previous</a>
</li>
<li class="page-item" th:classappend="${page == currentPage} ? 'active' : ''"
th:each="page : ${#numbers.sequence(1, totalPages != null ? totalPages : 1)}">
<a class="page-link" th:href="@{/member(page=${page})}" th:text="${page}"></a>
</li>
<li class="page-item" th:classappend="${currentPage < totalPages} ? '' : 'disabled'">
<a class="page-link" th:href="@{/member(page=${currentPage + 1})}">Next</a>
</li>
<li class="page-item" th:classappend="${currentPage < totalPages} ? '' : 'disabled'">
<a class="page-link" th:href="@{/member(page=${totalPages})}">Last</a>
</li>
</ul>
</nav>
classappend 를 활용하여 클래스를 조절해서 부트스트랩의 테마가 적용 될 수 있도록 하였다.
(사실 여기서 엄청 헤맸다......은근 복잡한데 다해놓고 보면 또 별거 아니넹)
728x90
320x100
'💻 뚝딱뚝딱 > 팀내도서대여시스템(OBRS)' 카테고리의 다른 글
[팀내도서대여시스템(OBRS) Ver.1)] 개발완료 보고 및 기능소개 / Ver2 개발예정인 기능 (0) | 2024.04.11 |
---|---|
[개발일지#011] 회원정보수정 수정하기 (0) | 2024.04.11 |
[개발일지#009] 로그인 / 로그아웃 / 회원가입 수정 및 구현 (0) | 2024.04.10 |
[개발일지#008] 나의책 / 빌린책 기능 구현 (0) | 2024.04.09 |
[개발일지#007] 책 수정 / 삭제 기능 수정 및 구현 (2) | 2024.04.08 |