๐Ÿ’ป ์ฝ”๋”ฉ ์ผ๊ธฐ : [Spring] '๊ฒŒ์‹œํŒ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌํ•˜๊ธฐ' ํŽธ

ybkยท2024๋…„ 5์›” 4์ผ

spring

๋ชฉ๋ก ๋ณด๊ธฐ
26/55
post-thumbnail

๐Ÿ”” '๊ฒŒ์‹œํŒ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌํ•˜๊ธฐ'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž!

Controller

@GetMapping("/")
public String home(@RequestParam(defaultValue = "1", value = "page")
                   Integer page, Model model) {
    // ๊ฒŒ์‹œ๋ฌผ ๋ชฉ๋ก ์กฐํšŒ(Select) ๋ชจ๋ธ์— ๋„ฃ๊ณ 
    model.addAllAttributes(service.list(page));
    //jsp๋กœ ํฌ์›Œ๋“œ
    return "board/home";
}
  • ์ฒ˜์Œ ๊ฒŒ์‹œํŒ ๋ชฉ๋ก์— ๋“ค์–ด๊ฐ”์„ ๋•Œ page=1์ด ๋ณด์ด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด @RequestParam(defaultValue="1")๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • addAllAttributes์€ Map์— ํฌํ•จ๋œ <ํ‚ค, ๊ฐ’>์„ ํ˜„์žฌ ๋ชจ๋ธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

Service

public Map<String, Object> list(Integer page) {
    int offset = (page - 1) * 10;

    int numberOfBoard = mapper.countAll();

    int lastPageNumber = (numberOfBoard - 1) / 10 + 1;
    int endPageNumber = ((page - 1) / 10 + 1) * 10;
    int beginPageNumber = endPageNumber - 9;
    endPageNumber = Math.min(endPageNumber, lastPageNumber);

    int prevPageNumber = beginPageNumber - 10;
    int nextPageNumber = beginPageNumber + 10;


    return Map.of("boardList", mapper.selectAllByPage(offset),
            "pageInfo", Map.of("lastPageNumber", lastPageNumber,
                    "endPageNumber", endPageNumber,
                    "beginPageNumber", beginPageNumber,
                    "prevPageNumber", prevPageNumber,
                    "nextPageNumber", nextPageNumber,
                    "currentPageNumber", page)
    );
}
  • Conroller์— ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด Map์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ณ  Map์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • offset : ์ฒซ ๋ฒˆ์งธ ํŽ˜์ด์ง€์—์„œ๋Š” 0๋ฒˆ๋ถ€ํ„ฐ 10๊ฐœ, ๋‘ ๋ฒˆ์งธ ํŽ˜์ด์ง€๋Š” 10๋ฒˆ๋ถ€ํ„ฐ 10๊ฐœ.. ์ด๋ ‡๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. page๊ฐ€ 1์ด๋ฉด ํ•œ ํŽ˜์ด์ง€์— 10๊ฐœ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์ด๋„๋ก ํ•˜๊ณ  page๊ฐ€ 2์ด๋ฉด 11๋ฒˆ๋ถ€ํ„ฐ 20๋ฒˆ๊นŒ์ง€ ๋ณด์ด๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • countAll() : ์ „์ฒด ๊ฒŒ์‹œ๊ธ€์˜ ๊ฐฏ์ˆ˜๋ฅผ ์œ„ํ•œ ์ฟผ๋ฆฌ
  • numberOfBoard = ์ „์ฒด ๊ฒŒ์‹œ๊ธ€
  • lastPageNumber = (์ „์ฒด ๊ฒŒ์‹œ๊ธ€ -1) / 10 + 1
  • endPageNumber์™€ beginPageNumber๋Š” 1~10, 11~20... ์ด๋ ‡๊ฒŒ 10๋‹จ์œ„์”ฉ ํŽ˜์ด์ง€๊ฐ€ ๋ณด์—ฌ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ ๊ณต์‹๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • int endPageNumber =((page - 1) / 10 + 1) * 10
    • beginPageNumber = endPageNumber - 9
  • endPageNumber๋Š” 10์”ฉ ๋Š์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— lastPageNumber ๋ณด๋‹ค ๋” ํฌ๊ธฐ ๋•Œ๋ฌธ์— MIN ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ lastPageNumber๋ณด๋‹ค ํฌ์ง€ ๋ชปํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

@Select("""
        SELECT * FROM board ORDER BY id DESC LIMIT #{offset}, 10
        """)
List<Board> selectAllByPage(int offset);

@Select("SELECT COUNT(*) FROM board")
int countAll();
  • selectAllByPage(int offset) : offset ์œผ๋กœ๋ถ€ํ„ฐ 10๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • countAll() : ์ „์ฒด ๊ฒŒ์‹œ๊ธ€์˜ ๊ฐฏ์ˆ˜๋ฅผ ์œ„ํ•œ ์ฟผ๋ฆฌ

<c:forEach begin="${pageInfo.beginPageNumber}" end="${pageInfo.endPageNumber}"
           var="pageNumber">
<c:url var="link" value="/">
    <c:param name="page" value="${pageNumber}"/>
</c:url>
<li class="page-item ${pageInfo.currentPageNumber eq pageNumber ? 'active' : ''}">
    <a class="page-link"
       href="${link}">${pageNumber}</a>
</li>
</c:forEach>

๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํ™”๋ฉด(home.jsp)

<%--์ด์ „--%>
<c:if test="${pageInfo.prevPageNumber > 0}">
<li class="page-item">
    <c:url var="prevPageLink" value="/">
        <c:param name="page" value="${pageInfo.prevPageNumber}"/>
    </c:url>
    <a class="page-link" href="${prevPageLink}" aria-label="Previous">
        <span aria-hidden="true">&laquo;</span>
    </a>
</li>

<%--๋‹ค์Œ--%>
<c:if test="${pageInfo.nextPageNumber < pageInfo.lastPageNumber}">
<li class="page-item">
    <c:url var="nextPageNumber" value="/">
        <c:param name="page" value="${pageInfo.nextPageNumber}"/>
    </c:url>
    <a class="page-link" href="${nextPageNumber}" aria-label="Next">
        <span aria-hidden="true">&raquo;</span>
    </a>
</li>
</c:if>
  • ์ด์ „ ๋ฒ„ํŠผ : ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ 1~10 ์‚ฌ์ด์— ์žˆ์„ ๋•Œ๋Š” ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ณ  ์ด์ „ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ด์ „ 10๋‹จ์œ„์˜ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ 34์ผ ๋•Œ ์ด์ „ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด 21๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ๋ฒ„ํŠผ : ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€์˜ 10๋‹จ์œ„์— ์žˆ์„ ๋•Œ๋Š” ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ณ  ๋‹ค์Œ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋‹ค์Œ 10 ๋‹จ์œ„์˜ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ 34์ผ ๋•Œ ๋‹ค์Œ ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด 41๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

<%--๋งจ ์ฒ˜์Œ--%>
<c:if test="${pageInfo.currentPageNumber > 1}">
<li class="page-item">
    <c:url var="fistPageLink" value="/">
        <c:param name="page" value="1"/>
    </c:url>
    <a class="page-link" href="${fistPageLink}" aria-label="Previous">
        <span aria-hidden="true">&laquo;&laquo;</span>
    </a>
</li>
</c:if>

<%--๋งจ ๋--%>
<c:if test="${pageInfo.currentPageNumber < pageInfo.lastPageNumber}">
<li class="page-item">
    <c:url var="lastPageLink" value="/">
        <c:param name="page" value="${pageInfo.lastPageNumber}"/>
    </c:url>
    <a class="page-link" href="${lastPageLink}" aria-label="Next">
        <span aria-hidden="true">&raquo;&raquo;</span>
    </a>
</li>
</c:if>
  • ๋งจ ์ฒ˜์Œ ๋ฒ„ํŠผ : ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ 1์ผ ๋•Œ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ณ  ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํŽ˜์ด์ง€ 1๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งจ ๋ ๋ฒ„ํŠผ : ํ˜„์žฌ ํŽ˜์ด์ง€๊ฐ€ ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ ์ผ ๋•Œ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๊ณ  ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

profile
๊ฐœ๋ฐœ์ž ์ค€๋น„์ƒ~

0๊ฐœ์˜ ๋Œ“๊ธ€