안녕하세요 민 입니다. 지금까지는 스프링의 개념과 구조에 대해서 열심히 알아보았는데요. 하지만 알고있다는 생각이 들어도 실제로 구현해보지 않으면 본인의 기술이 아니고, 코드를 구현한 후에 남에게 자기 코드를 설명해줄 때 막히는 부분이 있다면 이 또한 자신의 코드가 아니라고 생각합니다.
게시판 작성을 위한 간단한 기능(작성, 리스트, 디테일적인 부분)은 쉽게 작성하실 수 있지만 paging기법은 쉽지만 이해가 필요하다는 생각이 들어서 오늘은 코드와 함께 설명해드리겠습니다.
먼저 목차입니다. 따라오시죠!!
.
.
.
🥸 목차
1. 페이징 기법을 이용하기 위한 구조 설명
- 결과확인
- 느낀점
첫 번째입니다. 페이징 기법을 알기 위해서는 게시판에 대한 설명을 미룰 수 없는데요. 일단 Controller , Repository , DTO , Service 와 그 외의 정보를 알고있다는 전제로 시작하겠습니다.
현재 존재하는 파일들이 보이시죠??
BoardController
BoardDTO
BaordRepository
BoardService
마지막으로 (PageDTO)를 활용하여 페이징 기법을 할 예정이고,
추가적으로 페이징 기법을 처리할 페이지인 (paging.jsp) 파일 하나를 WEB-INF/views 안에 제작하겠습니다!
(사진을 준비하려 했지만 코드복사가 힘드실 것 같아 코드를 적어가며 보여드리겠습니다.)
@GetMapping("/paging")
public String paging(Model model,
@RequestParam(value = "page" , required = false , defaultValue = "1") int page){
List<BoardDTO> pagingList = boardService.pageList(page);
PageDTO pageDTO = boardService.pagingParam(page);
model.addAttribute("boardList", pagingList); // pagingList -> 한 페이지에 들어갈 게시글의 갯수를 지정
model.addAttribute("paging" , pageDTO); // 한 번에 몇 개의 페이지를 보이게 할 것인지에 대한 설명
return "paging";
}
} 입력하세요
자 이 코드를 보시면 BoardController 에서 /paging의 주소로 요청을 받으면 두 가지 로직을 실행시킨 이후에 "return paging"을 이용해서 값을 넘겨주는 걸 확인할 수 있습니다.
(boardService.pageList , boardService.pagingParam -> return "paging" )
여기서 두 가지 함수를 생각했습니다. 페이지를 사용하기 위해서는
한 페이지에 얼마나 많은 게시글을 올려둔 것인지에 대한
-> pageList라는 로직과
하단에 보이는 페이지를 몇 개나 보이게 할 것인지에 대한
-> pagingParam 이라는 로직
BoardController에서 BoardService의 객체를 이용해서 로직을 선언하고 있기 때문에 BoardService를 필수적으로 알아야합니다.
int pageLimit = 3; -> 한 페이지에 보여줄 게시물의 수
int blockLimit = 3; -> 하단에 보여줄 페이지의 수
public List<BoardDTO> pageList(int page) {
int pageStart = (page-1) * pageLimit + 1;
List<BoardDTO> pagingList = boardRepository.pageList(pageStart);
return pagingList;
}
public PageDTO pagingParam(int page) {
int boardCount = boardRepository.boardCount();
System.out.println(boardCount);
int maxPage = (int) (Math.ceil((double) boardCount / pageLimit));
// 시자페이지 값 계산
int startPage = (int)(Math.ceil((double) page / blockLimit) -1 ) * blockLimit + 1;
System.out.println(startPage);
int endPage = startPage + blockLimit -1;
if(endPage>maxPage){
endPage=maxPage;
}
System.out.println(page); --> check page
System.out.println(startPage); --> check startPage
System.out.println(maxPage); --> check maxPage
System.out.println(endPage); --> check endPage
PageDTO pageDTO = new PageDTO();
pageDTO.setPage(page);
pageDTO.setStartPage(startPage);
pageDTO.setMaxPage(maxPage);
pageDTO.setEndPage(endPage);
return pageDTO;
}
이건 인터넷에서 흔히 볼 수 있는 paging의 로직인데요.
간단히 말씀드리면 pageLimit과 blockLimit이라는 변수와 식을 이용해서 구하는 방식입니다.
사용자가 넣고싶은 한 페이지당 게시물의 수 -> pageLimit
사용자가 하단에 한 번에 보고싶은 페이지의 수 -> blockLimit
(필자는 머리속으로 숫자를 하나씩 넣어보면서 실제로 되는 것을 확인하니 이해가 더 쉬웠습니다. 머릿속으로 숫자를 하나씩 넣어보세요 !! )
이렇게 얻은 페이지의 값들을 PageDTO의 변수에 넣어주면 거의 80프로 왔습니다!!
package com.minjoCoader.board.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class PageDTO {
private int page; // 현재 페이지
private int maxPage; // 전체 필요한 페이지 갯수
private int startPage; // 현제 페이지 기준 시작 페이지 값
private int endPage; // 현재 페이지 기준 시작 페이지 값
}
``
위에 존재하는 boardRepository.pagingList과
boardRepository.boardCount 에 대해서 궁금하실 것 같아서
Mapper를 준비해보았습니다
boardCount --> 현재 존재하는 게시물의 개수
boardpagingList -> 한 페이지에 몇 개의 게시물을 넣을 건 지에 대한 로직
--> 위를 보시면 boradCount()라는 boardRepository.boardCount()는 boardMapper에 기록되어 있습니다 .
<select id="boardCount" resultType="Integer">
select count(id) from board_table ->
</select>
<select id="pagingList" parameterType="Integer" resultType="board">
select * from (select rownum num , B.* from board_table B) where num between #{pageStart} and #{pageStart} +2
</select>
DB에 접근해 값을 넘겨받는 것을 확인할 수 있습니다.
public List<BoardDTO> pageList(int pageStart) {
return sql.selectList("Board.pagingList" , pageStart);
}
public int boardCount() {
return sql.selectOne("Board.boardCount");
}
return "paging"으로 값을 넘겨주는데, 저는 .jsp로 경로를 설정해두어 paging.jsp로 향하게 됩니다. 여기서 JSTL을 이용해서 .jsp 파일을 작성했는데요. 먼저, JSTL이란 무엇인지 확인하고 가봅시다.
JSTL ( JSP Standard Tag Library)
-> 위에서 말하는 영어 그대로 JSP를 조금 더 편하고 쉽게 사용할 수 있는 공통적으로 사용되는 라이브러리 입니다.
JSTL을 사용하려면 지금까지와 동일하게 라이브러리 추가 후 JSP파일에 선언만 해주면 됩니다.
.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> --> 이걸 상단에 선언해서 사용할 수 있습니다 .
.
한 마디로 간단하게 정리하면 jsp라이브러리를 이용해서 조금 더 쉽고 깔끔하게 jsp파일을 작성할 수 있습니다.
자 이제 paging.jsp 파일을 확인하러 가실까요??
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Paging</title>
</head>
<body>
<div>
<table>
<tr>
<th>id</th>
<th>title</th>
<th>writer</th>
<th>date</th>
<th>hits</th>
</tr>
<c:forEach items="${boardList}" var="board">
<tr>
<td>${board.id}</td>
<td>
<a href="/board?id=">${board.boardTitle}</a>
</td>
<td>${board.boardWriter}</td>
<td>${board.boardCreatedTime}</td>
<td>${board.boardHits}</td>
</tr>
</c:forEach>
</table>
</div>
<div>
<c:choose>
<c:when test="${pading.page<=1}">
<span>이전</span>
</c:when>
<c:otherwise>
<a href="/board/paging?page=${paging.page-1}">이전</a>
</c:otherwise>
</c:choose>
<c:forEach begin="${paging.startPage}" end="${paging.endPage}" var="i" step="1">
<c:choose>
<c:when test="${i eq paging.page}">
<span>${i}</span>
</c:when>
<c:otherwise>
<a href="/board/paging?page=${i}">${i}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<c:choose>
<c:when test="${paging.page>=paging.maxPage}">
<span>다음</span>
</c:when>
<c:otherwise>
<a href="/board/paging?page=${paging.page+1}">다음</a>
</c:otherwise>
</c:choose>
</div>
</body>
</html
저희가 집중해야 할 부분은 JSTL을 이용한 <c: 부분입니다>
기존에 번거롭게 jsp 파일을 작성했던 것과 달리 조금 더 깔끔하고 정리된 버전으로 jsp 파일을 작성할 수 있습니다.
<c:forEach -> 반복문처럼 사용 가능
<c:when -> 기존의 if문처럼 if(i==paging.page) 라고 생각하면 됩니다.
<c:otherwise -> 영문 그대로 해당 경우가 아닌것을 생각
if(i!=paging.page)
구조를 보시면
<c:forEach> -> 반복문을 사용해야 할 필요가 있는 경우(선택)
<c:choose> -> 필수
<c:when>
(어떠한 경우가 작성된 곳 )
</c:when>
<c:otherwise>
(어떠한 경우가 아닌곳의 경우가 작성된 곳 )
</c:otherwise>
</c:choose>
</c:forEach>
.
이렇게 확인이 가능합니다.
BoardRepository
BoardService
BoardController
PostDTO
BoardMapper
Paging.jsp
JSTL 에 대해서 알아보는 시간이었습니다.
페이지 자체가 중요한 것은 아니라 작게 넣어뒀는데 보시면
이전과 1,2,3 다음 버튼의 페이징이 잘 적용된 것을 확인할 수 있습니다 .
spring으로 페이징을 적용해보면서 느낀점은 천천히 하면 할 만 하다였습니다. 여러분들도 차근차근 잘 적용해보시고, 코딩하시는 데 제 글이 조금이나마 도움이 됐음 좋겠습니다.
(JSTL 너무 편했고, jsp을 이용하다가 spring으로 이용하니까 코드 양이 너무 줄어서 편했습니다 . )
오늘 하루도 파이팅 !