Spring 게시판 프로젝트 (페이징 기법 , JSTL) 간단하게 배워보기 .

민이의 기술 노트 ·2023년 8월 18일
0

안녕하세요 민 입니다. 지금까지는 스프링의 개념과 구조에 대해서 열심히 알아보았는데요. 하지만 알고있다는 생각이 들어도 실제로 구현해보지 않으면 본인의 기술이 아니고, 코드를 구현한 후에 남에게 자기 코드를 설명해줄 때 막히는 부분이 있다면 이 또한 자신의 코드가 아니라고 생각합니다.

💁‍♂️ 그래서 오늘은 간단한 게시판 프로젝트를 제작해보았습니다 .

게시판 작성을 위한 간단한 기능(작성, 리스트, 디테일적인 부분)은 쉽게 작성하실 수 있지만 paging기법은 쉽지만 이해가 필요하다는 생각이 들어서 오늘은 코드와 함께 설명해드리겠습니다.
먼저 목차입니다. 따라오시죠!!

.
.
.

🥸 목차
1. 페이징 기법을 이용하기 위한 구조 설명


  1. 결과확인

  1. 느낀점

1. 페이징 기법을 이용하기 위한 구조 설명

첫 번째입니다. 페이징 기법을 알기 위해서는 게시판에 대한 설명을 미룰 수 없는데요. 일단 Controller , Repository , DTO , Service 와 그 외의 정보를 알고있다는 전제로 시작하겠습니다.

현재 존재하는 파일들이 보이시죠??
BoardController
BoardDTO
BaordRepository
BoardService
마지막으로 (PageDTO)를 활용하여 페이징 기법을 할 예정이고, 
추가적으로 페이징 기법을 처리할 페이지인 (paging.jsp) 파일 하나를 WEB-INF/views 안에 제작하겠습니다! 

(사진을 준비하려 했지만 코드복사가 힘드실 것 같아 코드를 적어가며 보여드리겠습니다.)

1-1 BoardController

 @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 이라는 로직

1-2 BoardService

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프로 왔습니다!!

1-3 PageDTO

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;  // 현재 페이지 기준 시작 페이지 값

}
``

1-4 boardMapper.xml

위에 존재하는 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>

1-5 BoardRepository

DB에 접근해 값을 넘겨받는 것을 확인할 수 있습니다.

 public List<BoardDTO> pageList(int pageStart) {
     return sql.selectList("Board.pagingList" , pageStart);
 }

 public int boardCount() {
     return sql.selectOne("Board.boardCount");
 }

1-6 paging.jsp

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 에 대해서 알아보는 시간이었습니다.

💁‍♂️ 2. 결과확인

페이지 자체가 중요한 것은 아니라 작게 넣어뒀는데 보시면
이전과 1,2,3 다음 버튼의 페이징이 잘 적용된 것을 확인할 수 있습니다 .

3.느낀점

spring으로 페이징을 적용해보면서 느낀점은 천천히 하면 할 만 하다였습니다. 여러분들도 차근차근 잘 적용해보시고, 코딩하시는 데 제 글이 조금이나마 도움이 됐음 좋겠습니다.
(JSTL 너무 편했고, jsp을 이용하다가 spring으로 이용하니까 코드 양이 너무 줄어서 편했습니다 . )

오늘 하루도 파이팅 !

profile
항상 성장하고 있는 개발자입니다!

0개의 댓글