ํ์ด์ง์ด๋?
์ด์์ฒด์ ๊ด์ ์์, ์ปดํจํฐ๊ฐ ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์์ ์ฌ์ฉํ๊ธฐ ์ํด 2์ฐจ ๊ธฐ์ต ์ฅ์น๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์ํ๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๊ธฐ๋ฒ์ด๋ค.
์๋ฅผ ๋ค์ด, 100๊ฐ์ ๊ฒ์๋ฌผ์ด ์์ผ๋ฉด ํ ํ์ด์ง์ 100๊ฐ๋ฅผ ๋ชจ๋ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด ์๋ 10๊ฐ์ฉ ๋๋ ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์ ํ์ด์ง ์ฒ๋ฆฌ๋ผ๊ณ ํ๋ค.

01. ํ์ด์ง ์ฒ๋ฆฌ
JPA์์ ์ ๊ณตํ๋ Pageable ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด์ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
01-1. BoardController์ boardList ๋ฉ์๋ ์์
๋ฉ์๋ ์ธ์์ Pageable ์ธํฐํ์ด์ค๋ฅผ ์ถ๊ฐํ๋ค. Pageable ์ธํฐํ์ด์ค๊ฐ ๋ง์๋ฐ ๊ทธ ์ค์ org.springframework.data.domain ์ธํฐํ์ด์ค๋ฅผ import ํด์ค๋ค.

• Pageable
- ์์ฒญํ ํ์ด์ง๋ฅผ ๋ฐํํ๋ค.
- JPA์์ ์ ๊ณตํด์ฃผ๋ ๊ฐ์ฒด์ด๋ค.
โป Pag๋ง ์ณ๋ ๊ด๋ จ ํด๋์ค๊ณผ ์ธํฐํ์ด์ค๋ค์ด ๊ฒ์๋๋ค. Tab์ผ๋ก ์ ํํ๋ฉด ๋๋ค.

• @PageableDefault
- Pageable ๊ฐ์ฒด ์์ @PageableDefault ์ ๋ ธํ ์ด์ ์ ๋ถ์ด๋ฉด ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ ์ ์๋ค.
- PageableHandlerMethodArgumentResolverSupport ์ ์ ์๋ getDefaultFromAnnotationOrFallback() ๋ฉ์๋์์ ํ์ธํ ์ ์๋ค.
- @PageDefault๋ก ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด ์๋ ๊ฒฝ์ฐ์๋ fallbackPageable์ด ์๋, @PageDefault์ด๋ ธํ ์ด์ ์ ์ค์ ํ๋๋ก ์ฌ์ฉ์์๊ฒ ๋ณด๋ด์ค๋ค.
- page : default ํ์ด์ง(ํ์ด์ง ์ธ๋ฑ์ค๊ฐ 1์ด ์๋ 0๋ถํฐ ์์)
- size : ํ ํ์ด์ง์ ๋ํ๋ผ ๊ฒ์๊ธ (์ฌ๊ธฐ์๋ 10๊ฐ๋ก ์ค์ )
- sort : ์ ๋ ฌ ๊ธฐ์ค ์ปฌ๋ผ (์ฌ๊ธฐ์๋ id๊ฐ์ผ๋ก ์ ๋ ฌ)
- direction : ์ ๋ ฌ ์์
- DESC : ์ญ์์ผ๋ก ์ ๋ ฌ(๋ด๋ฆผ์ฐจ์์ด๋ ๋ป์ผ๋ก ํฐ ๊ฐ์ด ์ ์ผ ๋จผ์ ์ค๋๋ก ์ฆ, ์ต์ ํ์ด์ง๊ฐ ์์์ ์ค๋๋ก ์ฒ๋ฆฌ)
- ASC : DESC์ ๋ฐ๋๋ก ์ค๋ฆ์ฐจ์์ด๋ผ๋ ๋ป์ด๋ค. ๋ํดํธ ๊ฐ์ด๋ฏ๋ก ์๋ต์ด ๊ฐ๋ฅํ๋ค.
์ธ์๋ก ๋ฐ์ pageable์ boardList์ ๋๊ฒจ์ค๊ฑด๋ฐ ํ์ฌ ์ค๋ฅ๊ฐ ๋๋ค. ์ด๋ ์๋น์ค์์ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ง ์์์ ์๊ธด ๋ฌธ์ ์ด๋ค. ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด Service์์ List ๋ฉ์๋๋ฅผ ์์ ํ๋ค.
โค Pageable์ ๋ํ ์์ธํ ์ค๋ช โ https://tecoble.techcourse.co.kr/post/2021-08-15-pageable/
01-2. BoardService์ boardList ๋ฉ์๋ ์์

pageable ๋งค๊ฐ๋ณ์๋ฅผ ๋ฃ์ด์ฃผ๋ ์ค๋ฅ๊ฐ ๋๋ค. List์๋ฆฌ์ Page๋ก ๋ณ๊ฒฝํ๋ฉด ์ค๋ฅ๊ฐ ์ฌ๋ผ์ง๋ค.

Controller๋ ๋ค์ ํ์ธํ๋ฉด ์ค๋ฅ๊ฐ ์ฌ๋ผ์ง ๊ฒ์ ๋ณผ ์ ์๋ค.

์คํํ๊ธฐ(http://localhost:8080/board/list)


๊ธฐ์กด์๋ ๋ชจ๋ ๊ฒ์๊ธ์ด ํ ํ์ด์ง์ ๋ค ๋ณด์์ง๋ง, PageableDefault๋ฅผ ํตํด ํ์ด์ง ์ฒ๋ฆฌํ ๊ฒฐ๊ณผ ์ต์ ๊ธ์ด ๋งจ ์๋ก ์ฌ๋ผ์จ ๊ฑธ ๋ณผ ์ ์๊ณ , ํ ํ์ด์ง์ 10๊ฐ์ ๊ฒ์๊ธ๋ง ๋ณด์ด๋ ๊ฑธ ์ ์ ์์ต๋๋ค.
ํ์ฌ๋ 0ํ์ด์ง(์ฒซ ๋ฒ์งธ ํ์ด์ง)๋ง ๋ณด์ด์ง๋ง, url์ ์์ ํด ๋ค๋ฅธ ํ์ด์ง๋ฅผ ํ์ธํด ๋ณผ ์ ์๋ค. 0์๋ฆฌ์ 1์ ๋ฃ์ผ๋ฉด ๋ ๋ฒ์งธ ํ์ด์ง๋ก ๋์ด๊ฐ๋ค.


ํ ํ์ด์ง์ ๋ณด์ฌ์ค ๊ฒ์๊ธ์ ์๋ ์ง์ ํด ์ค ์ ์๋ค. url์ size๋ ๋๊ฒจ์ฃผ๋ ๊ฒ์ด๋ค.

size = 20 ์ฆ, ์ฒซ ๋ฒ์งธ ๊ฒ์๋ฌผ์ 20๊ฐ์ ๊ฒ์๋ฌผ์ ๋ณด๊ฒ ๋ค๋ ๋ง์ด๋ค.
์ ๋ฆฌํ๋ฉด, ํ์ด์ง ์ฒ๋ฆฌ ์์ ์ฟผ๋ฆฌ๋ฌธ ์์ฑ๊ณผ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํ ํด๋์ค๋ ์์ฑํด์ค์ผ ํ๋๋ฐ ์ด๋, jpa๋ฅผ ์ด์ฉํ๋ค. jpa์ findAll ํจ์๋ฅผ ์ฌ์ฉํ ๋ pageable ํด๋์ค๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ์ด๋ ค์ด ์ฒ๋ฆฌ๋ฅผ ์ด๋ ๊ฒ ๊ฐ๋จํ๊ฒ ํ ์ ์๋ค.
02. ํ์ด์ง ๋ธ๋ญ ์ถ๋ ฅ
์ด์ ํ๋ก ํธ ์ฆ, ๋ฆฌ์คํธ ํ์ด์ง์ ๋ค์ ํ์ด์ง๋ก ํด๋ฆญ์ผ๋ก ์ด๋ํ ์ ์๊ฒ ๋ณด์ฌ์ค๋ค.
02-1. boardlist.html์ thymeleaf ์ถ๊ฐ
<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
.
.
<body>
<div class="layout">
<table border="1" align="center"> <!-- ๋ฆฌ์คํธ ์ค๊ฐ ์ ๋ ฌ ์ถ๊ฐ -->
.
.
</table>
<!-- ํ์ด์ง ๋ธ๋ญ ์ฒ๋ฆฌ thymeleaf ์ถ๊ฐ -->
<nav style="text-align: center;"> <!-- ํ์ด์ง ๋ธ๋ญ๋ ์ค๊ฐ ์ ๋ ฌ ์ถ๊ฐ -->
<th:block th:each="page : ${#numbers.sequence(startPage, endPage)}">
<a th:if="${page != nowPage}" th:href="@{/board/list(page = ${page - 1})}" th:text="${page}"></a>
<strong th:if="${page == nowPage}" th:text="${page}" style="color : red"></strong>
</th:block>
</nav>
</div>
</body></html>
• thymeleaf ๋ฌธ๋ฒ
- th:text - ํ๊ทธ ์์ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅ
- Thymeleaf์ th:text ์์ฑ์ ์์ ์ ํ ์คํธ ๋ด์ฉ์ ์ค์ ํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
- ๋ํ ์ด๋ ํ์ค HTML ํ ์คํธ ์์ฑ์ ๋์ฒดํ๋ค.
- ๋ฐ๋ผ์ ์ ๋ชฉ, ๋จ๋ฝ, ๋ ์ด๋ธ ๋ฑ๊ณผ ๊ฐ์ ํ ์คํธ ์ฝํ ์ธ ๋ฅผ ์ง์ํ๋ ๋ชจ๋ HTML ์์ ๋ด์ ์ด๋ฅผ ๋ฃ์ ์ ์๋ค.
- ๋ํ ์ด ์์ฑ์ ์ฌ์ฉํ์ฌ ์น ํ์ด์ง์ ์ ๋ชฉ๊ณผ ๊ฐ์ ๋์ ํ ์คํธ ์ฝํ ์ธ ๋ฅผ ํ์ํ ์ ์๋ค.
- th:each - ๋ฐ๋ณต๋ฌธ, ๋ฐ๋ณต ์ถ๋ ฅ
- th:each = "board : ${boardList}" - ๊ธฐ๋ณธ ๋ฌธ๋ฒ์ผ๋ก, ํ์ดํ๋ฉด boardList์ ๊ฐ๋ค์ board๊ฐ ํ๋ํ๋ ์ฐธ์กฐํ๋ค.
- "${number : #number(์์ ๋ฒํธ, ๋๋ฒํธ)}" - ์์ ๋ฒํธ์์ ๋๋ฒํธ๊น์ง ๋ฐ๋ณต
02-2. BoardController์ boardList ๋ฉ์๋ ์์

1. "List"์ ๋๊ฒจ์ค ํ์ด์ง๋ฅผ ์ง์ ๋๊ฒจ์ฃผ์ง ์๊ณ ๋ฐ๋ก ๊ตฌํํ๋ค. ๊ฐ์ ์ฝ๋๋ฅผ ๋ค๋ฅธ ๊ณณ์๋ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด์ ๋ถํ์ํ ๋ฐ๋ณต์ ์ค์ด๊ณ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ธฐ ์ํ ๊ฒ์ด๋ค.
//์ถ๊ฐ
Page<Board> list = boardService.boardList(pageable);
2. ๊ฐ์ฒด๋ฅผ ๋ง๋ค์์ผ๋ list๋ฅผ ๋ด์์ค๋ค. ๊ธฐ์กด์๋ list ์๋ฆฌ์ 'boardService.boardList(pageable));'๊ฐ ์์๋ค.
//์์
model.addAttribute("List", list);
3. ๋ณ์๋ฅผ ๋ง๋ ๋ค.
int nowPage = list.getPageable().getPageNumber() + 1; //ํ์ฌ ํ์ด์ง
int startPage = nowPage / pageable.getPageSize() * pageable.getPageSize() + 1; //๋ธ๋ญ์์ ๋ณด์ฌ์ค ์์ ํ์ด์ง
int endPage = startPage + pageable.getPageSize() - 1; //๋ธ๋ญ์์ ๋ณด์ด๋ ๋ง์ง๋ง ํ์ด์ง
- nowPage
- ํ์ฌ ํ์ด์ง๋ฅผ ์๋ฏธํ๊ณ , ํ์ฌ ํ์ด์ง๋ฅผ ๋๊ฒจ์ค๋ค.
- nowPage์ pageable.getPageNumber()๋ง ๋๊ฒจ์ค๋ ๋์ง๋ง ํต์ผ์ฑ์ ์ํด ์์ ๊ฐ์ด ์์ฑํ๋ค.
- startPage
- ๋ธ๋ญ์์ ๋ณด์ฌ์ค ์์ ํ์ด์ง๋ฅผ ์๋ฏธํ๋ค.
- ํ์ฌํ์ด์ง/ํ์ด์ง ๊ฐ์*ํ์ด์ง ๊ฐ์ + 1
- endPage
- ๋ธ๋ญ์์ ๋ณด์ด๋ ๋ง์ง๋ง ํ์ด์ง๋ฅผ ์๋ฏธํ๋ค.
- ์์ํ์ด์ง + ํ์ด์ง ๊ฐ์ - 1
4. ๋ณ์ ์ค์ ์ด ๋๋ฌ์ผ๋ฉด ๊ฐ์ ๋๊ฒจ์ค๋ค.
//์ถ๊ฐ
model.addAttribute("nowPage", nowPage);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
์คํํ๊ธฐ(localhost:8080/board/list)

์์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ ์ปจํธ๋กค๋ฌ์ boardList์์ 10๊ฐ ๋จ์๋ก ๋์ค๋๋ก ์ค์ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
'๐ป PROJECT > [์คํ๋ง ๋ถํธ] ๊ฒ์ํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [์คํ๋ง ๋ถํธ] 8. ๊ฒ์ํ ๋ง๋ค๊ธฐ ๋ฉ์์ง ์ฐฝ ๋์ฐ๊ธฐ (0) | 2023.10.26 |
|---|---|
| [์คํ๋ง ๋ถํธ] 7. ๊ฒ์ํ ๋ง๋ค๊ธฐ ์์ ์ฒ๋ฆฌ (1) | 2023.10.26 |
| [์คํ๋ง ๋ถํธ] 6. ๊ฒ์ํ ๋ง๋ค๊ธฐ ์ญ์ ์ฒ๋ฆฌ (0) | 2023.10.25 |
| [์คํ๋ง ๋ถํธ] 5. ๊ฒ์ํ ๋ง๋ค๊ธฐ ๊ฒ์๋ฌผ ๋ฆฌ์คํ (0) | 2023.10.24 |
| [์คํ๋ง ๋ถํธ] 4. ๊ฒ์ํ ๋ง๋ค๊ธฐ ๊ฒ์๊ธ ์์ฑํผ ์์ฑ๊ณผ ์ฒ๋ฆฌ (1) | 2023.10.23 |