오늘 공부할 주제
@PageableDefault() 어노테이션
Github 코드 보기
1. Controller수정하기
기존에는 글 관련 정보만 jsp 페이지로 전달했지만 추가적으로 페이지에 대한 정보도 같이 보내기 위해 다음과 같이 코드를 작성하였다.
// BoardController 클래스
@GetMapping({"", "/"})
public String index(Model model,
@PageableDefault(size = 5, sort = "id", direction = Sort.Direction.DESC)Pageable pageable){
boardService.글목록(model, pageable);
return "index";
}
먼저 파라미터로 @PageableDefault 어노테이션을 사용하여 페이지에 대한 옵션을 설정한다
size는 한페이지당 글의 갯수이며, sort는 어떤 컬럼을 기준으로 정렬할 것인지, direction은 내림차순인지 오름차순인지 설정해준다.
Pageable타입으로 boardService의 글목록() 메소드의 파라미터로 추가 전달 해준다.
2. Service 수정하기
기존의 코드에서는 단순하게 board의 정보들만 보내면 되었기에 controller단에 addAttribute()메소드를 작성하였지만,
이번에는 몇가지 더 전달하기 위해 기존코드와 함께 Service딴으로 가져왔다.
//BoardService 클래스
@Transactional
public void 글목록(Model model, Pageable pageable){
Page<Board> blist = boardRepository.findAll(pageable);
int pageNumber = blist.getPageable().getPageNumber(); // 현재페이지
int totalPages = blist.getTotalPages();
int pageBlock = 5;
int startBlockPage = ( ( (pageNumber/pageBlock) * pageBlock) + 1);
int endBlockPage = startBlockPage + pageBlock - 1;
endBlockPage = totalPages<endBlockPage? totalPages:endBlockPage;
model.addAttribute("startBlockPage", startBlockPage);
model.addAttribute("endBlockPage", endBlockPage);
model.addAttribute("boards", blist);
}
JpaRepository클래스의 findAll()메소드의 파라미터로 Pageable 변수를 넣어준 후에 Page<Board> 타입으로 받아준다.
여기서 얻은 정보를 토대로 시작 페이지번호와 마지막 페이지번호를 계산하여 변수에 담아준다.
이렇게 산정된 첫번째 페이지, 마지막 페이지, 글정보를 model 객체를 통해 jsp 페이지로 전달한다.
3. 홈페이지 수정하기
이제 우리가 불러온 글들 아래쪽으로 페이지를 표시하기 위해 bootstrap5을 이용하여 약간의 커스텀을 해준다.
// index.jsp
<%-- 처음 --%>
<ul class="pagination justify-content-center">
<c:choose>
<c:when test="${boards.first}">
<li class="page-item disabled"><a class="page-link" href="?page=0">처음</a></li>
<li class="page-item disabled"><a class="page-link" href="?page=${boards.number-1}">◀</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="?page=0">처음</a></li>
<li class="page-item"><a class="page-link" href="?page=${boards.number-1}">◀</a></li>
</c:otherwise>
</c:choose>
<%-- 페이지 그룹 --%>
<c:forEach begin="${startBlockPage}" end="${endBlockPage}" var="i">
<c:choose>
<c:when test="${boards.pageable.pageNumber+1 == i}">
<li class="page-item disabled"><a class="page-link" href="?page=${i-1}">${i}</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="?page=${i-1}">${i}</a></li>
</c:otherwise>
</c:choose>
</c:forEach>
<%-- 마지막 --%>
<c:choose>
<c:when test="${boards.last}">
<li class="page-item disabled"><a class="page-link" href="?page=${boards.number+1}">▶️️</a></li>
<li class="page-item disabled"><a class="page-link" href="?page=${boards.totalPages-1}">마지막</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="?page=${boards.number+1}">▶️️</a></li>
<li class="page-item"><a class="page-link" href="?page=${boards.totalPages-1}">마지막</a></li>
</c:otherwise>
</c:choose>
</ul>
글정보를 불러온 것과 같이 jstl 문법과 jsp 문법을 이용하여 Service에서 보낸정보를 받겠다.
"${boards.first}"와 "${boards.last}"는 글정보가 첫 번째나 마지막일 경우 disabled속성을 이용하여 해당 태그를 비활성화 하게 된다.
forEach에서는 begin의 값부터 end까지의 값을 var에 담아서 차례대로 표시해준다. 페이지는 0부터 시작하므로 이점은 주의해서 페이지 표시를 해주어야한다. 우리가 계산한 startBlockPage와 endBlockPage는 5개 단위로 바뀌도록 계산해놓았기 때문에 한 페이지당 [처음, ◀, 1,2,3,4,5,▶️마지막] 이런식으로 표현 될 것이다.
그리고 현재 페이지에 해당하는 페이지번호도 비활성화 하기위해 choose를 사용해주었다.
4. 테스트를 위한 더미데이터 Procedure 만들기
이제 여러 페이지에 여러 글을 통해 페이징처리가 되었는지 확인해야되는데
일일이 글작성을 하고 있을 순 없으니 데이터베이스에 반복 프로시저 하나를 만들어서 데이터를 넣어보겠다.
참고로 더미데이터를 넣는법을 찾다가 문장의 앞뒤로 DELIMITER $$를 붙여주는 글을 많이 보았는데,
나는 왜인지 이거 때문에 쿼리가 안먹어서 이 두개와 $$를 모두 제거하고 사용하였더니 작동이 되었다.
아마 delimeter의 기능은 쿼리문의 구분을 위한 것인데 CLI로 쿼리를 작성할때는 사용하지만 우리와 같이 GUI를 기반으로
쿼리를 작성한다면 굳이 없어도 무방한듯 하다.
show procedure status;
drop procedure loopInsert;
CREATE PROCEDURE loopInsert()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 100 DO
INSERT INTO Board(title , content, count, createTime)
VALUES(concat('제목',i), concat('내용',i),0, now());
SET i = i + 1;
END WHILE;
END
CALL loopInsert;
먼저 같은 이름의 프로시저가 존재하는지 확인 후 있다면 drop 해준다.
그리고 위와 같은 형식으로 프로시저를 생성한 후 CALL 프로시저명 을 통해 프로시저를 작동해주면 된다!
프로시저에 나오는 문법과 같은경우는 간단하기 때문에 처음보아도 어떤 의미인지 해석이 가능하다.
Board 테이블을 확인하니 정상적으로 잘 들어간듯 하다. 아마 나중에 글 상세페이지를 작성할 때는 userId도 필요하기 때문에 차후에 프로시저를 수정해주도록 하겠다.
5. 페이징 처리 완료
여기까지 에러없이 코딩을 하였다면 이제 프로젝트는 정상적으로 작동할 것이다.
홈페이지로 접속하면 로그인 없이도 바로 확인이 가능하다.
한페이지당 5개의 게시물과 5개의 페이지번호가 정상적으로 표현이 되었고, 맨처음 페이지와 ◀ 그리고 현재페이지는 비활성화가 되어 있는 것을 확인 할 수 있다.
5페이지를 넘어가면 다음 5개의 페이지 번호가 정상적으로 표현되는 것이 확인된다.
마지막 페이지를 클릭해보면 마지막 2개의 글정보와 비활성화 된 링크들을 확인 할 수있다.
jsp와 jstl문법을 사용하다보니 클라이언트 페이지의 코드가 점점 복잡해지는 것이 느껴진다.
차후에 서버사이드에서 모든 로직을 처리한 뒤 페이지로 보내는 방법에 대해서도 공부해 봐야겠다.
'개인 프로젝트 > 블로그 만들기' 카테고리의 다른 글
나의 블로그 만들기 프로젝트 (9일차) - 글 상세정보, 글 수정 완료 (0) | 2023.04.07 |
---|---|
나의 블로그 만들기 프로젝트 (7일차) - 글 목록 뿌리기 (0) | 2023.04.05 |
나의 블로그 만들기 프로젝트 (6일차) - 글쓰기 완료 (0) | 2023.04.05 |
나의 블로그 만들기 프로젝트 (5일차) - 로그인 처리 (0) | 2023.04.02 |
나의 블로그 만들기 프로젝트 (4일차) - 회원가입 처리 (0) | 2023.04.01 |