커뮤티니에 드롭다운에 게시판을넣어 나중에 다른 드롭다운이 추가되더라도 어색하지 않을수있다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="layouts/layout.html">
<!-- layout을 사용하기위해 추가 -->
<head>
<!-- jquery cdn -->
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<!-- css 링크 코드 -->
<link rel="stylesheet" th:href="@{/css/paging.css}">
</head>
<body>
<div layout:fragment="content">
<!-- layouts/layout.html에 있는 content에 들어가는 부분 -->
<div class="container text-center mt-5">
<table class="table center" style="color:black;">
<thead class="thead-dark">
<tr>
<th>NO</th>
<th>제목</th>
<th>작성자</th>
<th>시간</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
<tr th:each="board: ${boardList}">
<td th:text="${board.id}"></td>
<!-- 글의 No 값을 넣기위한 코드 -->
<td><a th:href="@{|/capoeiraweb/${board.id}|(page=${boardList.number + 1})}" th:text="${board.boardTitle}"></a></td>
<!-- 글제목에 값을 넣기위한 코드 -->
<td th:text="${board.boardWriter}"></td>
<!-- 작성자에 값을 넣기위한 코드 -->
<td th:text="*{#temporals.format(board.boardCreatedTime, 'yyyy-MM-dd')}"></td>
<!-- 작성글 작성 시간에 값을 넣기위한 코드 -->
<td th:text="${board.boardHits}"></td>
<!-- 조회수에 값을 넣기위한 코드 -->
</tr>
</tbody>
</table>
</div>
<div class="container text-right mt-5">
<a th:href="${session.loginNickname != null} ? '/capoeiraweb/save' : '/capoeiraweb/login'" class="btn btn-primary">글 작성하기</a>
<!-- 헤더의 닉네임(즉 로그인)이 안되어있으면 삼항연산자를 통해 참이면 글작성 페이지로 거짓이면 로그인을 할수있게 로그인 페이지로 넘어가게 하는 코드 -->
</div>
<div class="container text-center mt-5">
<!-- 첫번째 페이지로 이동 -->
<!-- /board/paging?page=1 -->
<a th:href="@{/capoeiraweb/paging(page=1)}">First</a>
<!-- 이전 링크 활성화 비활성화 -->
<!-- boardList.getNumber() 사용자:2페이지 getNumber()=1 -->
<a th:href="${boardList.first} ? '#' : @{/capoeiraweb/paging(page=${boardList.number})}">prev</a>
<!-- 페이지 번호 링크(현재 페이지는 숫자만)
for(int page=startPage; page<=endPage; page++)-->
<span th:each="page: ${#numbers.sequence(startPage, endPage)}">
<!-- 현재페이지는 링크 없이 숫자만 -->
<span th:if="${page == boardList.number + 1}" th:text="${page}"></span>
<!-- 현재페이지 번호가 아닌 다른 페이지번호에는 링크를 보여줌 -->
<span th:unless="${page == boardList.number + 1}">
<a th:href="@{/capoeiraweb/paging(page=${page})}" th:text="${page}"></a>
</span>
</span>
<!-- 다음 링크 활성화 비활성화
사용자: 2페이지, getNumber: 1, 3페이지-->
<a th:href="${boardList.last} ? '#' : @{/capoeiraweb/paging(page=${boardList.number + 2})}">next</a>
<!-- 마지막 페이지로 이동 -->
<a th:href="@{/capoeiraweb/paging(page=${boardList.totalPages})}">Last</a>
</div>
</div>
</body>
</html>
package capoeira.capoeiraweb.controller;
import capoeira.capoeiraweb.dto.BoardDTO;
import capoeira.capoeiraweb.dto.CommentDTO;
import capoeira.capoeiraweb.service.BoardService;
import capoeira.capoeiraweb.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
@Controller
@RequiredArgsConstructor
@RequestMapping("/capoeiraweb")
<!-- @RequestMapping("/capoeiraweb") 경로를 좀더 편하게 쓸수있게 추가한 코드
원래라면 @GetMapping("/capoeiraweb/save") 계속 써줘야 하지만 @RequestMapping
을 통해 좀더 코드를 쓸때 편하게 쓸수있다
-->
public class BoardController {
private final BoardService boardService;
private final CommentService commentService;
@GetMapping("/save")
public String saveForm() {
return "save";
}
@PostMapping("/save")
public String save(@ModelAttribute BoardDTO boardDTO) throws IOException {
System.out.println("boardDTO = " + boardDTO);
boardService.save(boardDTO);
return "redirect:/capoeiraweb/paging";
}
@GetMapping("/")
public String findAll(Model model) {
// DB에서 전체 게시글 데이터를 가져와서 list.html에 보여준다.
List<BoardDTO> boardDTOList =boardService.findAll();
model.addAttribute("boardList", boardDTOList);
return "list";
}
@GetMapping("/{id}")
public String findById(@PathVariable long id, Model model,
@PageableDefault(page=1) Pageable pageable) {
/*
해당 게시글의 조회수를 하나 올리고
게시글 데이터를 가져와서 detail.html에 출력
*/
boardService.updateHits(id);
BoardDTO boardDTO = boardService.findById(id);
/* 댓글 목록 가져오기 */
List<CommentDTO> commentDTOList = commentService.findAll(id);
model.addAttribute("commentList", commentDTOList);
model.addAttribute("board", boardDTO);
model.addAttribute("page", pageable.getPageNumber());
return "detail";
}
@GetMapping("update/{id}")
public String updateForm(@PathVariable Long id, Model model) {
BoardDTO boardDTO = boardService.findById(id);
model.addAttribute("boardUpdate", boardDTO);
return "update";
}
@PostMapping("/update")
public String update(@ModelAttribute BoardDTO boardDTO, Model model) {
BoardDTO board = boardService.update(boardDTO);
model.addAttribute("board", board);
return "redirect:/capoeiraweb/" + boardDTO.getId();
}
@GetMapping("/delete/{id}")
private String delete(@PathVariable Long id) {
boardService.delete(id);
return "redirect:/capoeiraweb/paging";
}
// /board/paging?page=1
@GetMapping("/paging")
public String paging(@PageableDefault(page = 1) Pageable pageable, Model model) {
// pageable.getPageNumber();
Page<BoardDTO> boardList = boardService.paging(pageable);
int blockLimit = 3; // 보여지는 페이지의 갯수 3개
int startPage = (((int)(Math.ceil((double)pageable.getPageNumber() / blockLimit))) - 1) * blockLimit + 1; // 1 4 7 10 ~~
int endPage = ((startPage + blockLimit - 1) < boardList.getTotalPages()) ? startPage + blockLimit - 1 : boardList.getTotalPages();
// page 갯수 20개
// 현재 사용자가 3페이지
// 1 2 3
// 현재 사용자가 7페이지
// 7 8 9
// 보여지는 페이지 갯수 3개
model.addAttribute("boardList", boardList);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
return "paging";
}
}
boardController 에서 사용하고있는 맵핑