Controller
package com.board.study.web;
import com.board.study.dto.board.BoardRequestDto;
import com.board.study.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RequiredArgsConstructor
@Controller
public class BoardController {
private final BoardService boardService;
@GetMapping("/board/list")
public String getBoardListPage(Model model, @RequestParam(required = false, defaultValue = "0") Integer page, @RequestParam(required = false, defaultValue = "5") Integer size) throws Exception {
try {
model.addAttribute("resultMap", boardService.findAll(page, size));
} catch (Exception e) {
throw new Exception(e.getMessage());
}
return "/board/list";
}
@GetMapping("/board/write")
public String getBoardWritePage(Model model, BoardRequestDto boardRequestDto) {
return "/board/write";
}
@GetMapping("/board/view")
public String getBoardViewPage(Model model, BoardRequestDto boardRequestDto) throws Exception {
try {
if (boardRequestDto.getId() != null) {
model.addAttribute("info", boardService.findById(boardRequestDto.getId()));
}
} catch (Exception e) {
throw new Exception(e.getMessage());
}
return "/board/view";
}
@PostMapping("/board/write/action")
public String boardWriteAction(Model model, BoardRequestDto boardRequestDto) throws Exception {
try {
Long result = boardService.save(boardRequestDto);
if (result < 0) {
throw new Exception("#Exception boardWriteAction!");
}
} catch (Exception e) {
throw new Exception(e.getMessage());
}
return "redirect:/board/list";
}
}
Service
기존에 작성했던 서비스에서 페이징 처리를 위한 코드를 추가 했다.
Spring Data JPA에서는 페이징 처리를 위한 PageRequest 객체를 지원한다.
package com.board.study.service;
import com.board.study.dto.board.BoardRequestDto;
import com.board.study.dto.board.BoardResponseDto;
import com.board.study.entity.Board;
import com.board.study.repository.BoardRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@RequiredArgsConstructor
@Service
public class BoardService {
private final BoardRepository boardRepository;
@Transactional
public Long save(BoardRequestDto boardRequestDto) {
return boardRepository.save(boardRequestDto.toEntity()).getId();
}
// @Transactional(readOnly = true)
// public List<BoardResponseDto> findAll() {
// return boardRepository.findAll().stream().map(BoardResponseDto::new).collect(Collectors.toList());
// }
@Transactional(readOnly = true)
public HashMap<String, Object> findAll(Integer page, Integer size) {
HashMap<String, Object> resultMap = new HashMap<String, Object>();
Page<Board> list = boardRepository.findAll(PageRequest.of(page, size));
resultMap.put("list", list.stream().map(BoardResponseDto::new).collect(Collectors.toList()));
resultMap.put("paging", list.getPageable());
resultMap.put("totalCnt", list.getTotalElements());
resultMap.put("totalPage", list.getTotalPages());
return resultMap;
}
public BoardResponseDto findById(Long id) {
return new BoardResponseDto(boardRepository.findById(id).get());
}
public int updateBoard(BoardRequestDto boardRequestDto) {
return boardRepository.updateBoard(boardRequestDto);
}
// public int updateBoardReadCntInc(Long id) {
// return boardRepository.updateBoardReadCntInc(id);
// }
public void deleteById(Long id) {
boardRepository.deleteById(id);
}
}
목록
Thymeleaf를 이용하여 데이터 처리
list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Board List</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--부트스트랩 css 추가-->
<link rel="stylesheet" href="/css/lib/bootstrap.min.css">
</head>
<body>
<div id="wrapper">
<div class="container">
<div class="col-md-12">
<table class="table table-striped table-horizontal table-bordered mt-3">
<thead class="thead-strong">
<tr>
<th width="10%">게시글번호</th>
<th width="">제목</th>
<th width="20%">작성자</th>
<th width="20%">작성일</th>
</tr>
</thead>
<tbody id="tbody">
<tr th:each="list,index : ${resultMap.list}" th:with="paging=${resultMap.paging}">
<td> <!--0부터 시작 0부터 시작-->
<span th:text="${(resultMap.totalCnt - index.index) - (paging.pageNumber * paging.pageSize)}"></span>
</td>
<td>
<a th:href="@{./view(id=${list.id})}"><span th:text="${list.title}"></span></a>
</td>
<td>
<span th:text="${list.registerId}"></span>
</td>
<td>
<span th:text="${list.registerTime}"></span>
</td>
<tr>
</tbody>
</table>
<div class="row">
<div class="col">
<ul class="pagination">
<li class="page-item" th:each="index : ${#numbers.sequence(1, resultMap.totalPage)}" th:with="paging=${resultMap.paging}">
<a class="page-link" th:href="@{./list(page=${index - 1},page=${paging.pageSize})}"><span th:text="${index}"></span></a>
</li>
</ul>
</div>
</div>
<button type="button" class="btn btn-danger" onclick="fnDelete()">Delete</button>
<button type="button" class="btn btn-primary" onclick="javascript:location.href='/board/write'">Register</button>
</div>
</div>
</div>
<!--부트스트랩 js, jquery 추가-->
<script src="/js/lib/jquery.min.js"></script>
<script src="/js/lib/bootstrap.min.js"></script>
</body>
</html>
등록
write.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Board List</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--부트스트랩 css 추가-->
<link rel="stylesheet" href="/css/lib/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Board Register.</h1>
<form action="/board/write/action" method="post">
<div class="mb-3">
<label class="form-label">Title.</label>
<input type="text" class="form-control" id="" name="title">
</div>
<div class="mb-3">
<label class="form-label">Content</label>
<textarea class="form-control" rows="5" cols="" name="content"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Writer.</label>
<input type="text" class="form-control" id="" name="registerId">
</div>
<button type="button" class="btn btn-success" onclick="javascript:location.href='/board/list'">Previous</button>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<!--부트스트랩 js, jquery 추가-->
<script src="/js/lib/jquery.min.js"></script>
<script src="/js/lib/bootstrap.min.js"></script>
</body>
</html>
상세
view.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Board List</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--부트스트랩 css 추가-->
<link rel="stylesheet" href="/css/lib/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Board View.</h1>
<div class="mb-3">
<label class="form-label">Title.</label>
<input type="text" class="form-control" id="" name="" th:value="${info.title}">
</div>
<div class="mb-3">
<label class="form-label">Content</label>
<textarea class="form-control" rows="5" cols="" name="" th:text="${info.content}"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Writer.</label>
<input type="text" class="form-control" id="" name="" th:value="${info.registerId}">
</div>
<button type="button" class="btn btn-success" onclick="javascript:location.href='/board/list'">Previous</button>
</div>
<!--부트스트랩 js, jquery 추가-->
<script src="/js/lib/jquery.min.js"></script>
<script src="/js/lib/bootstrap.min.js"></script>
</body>
</html>
사용된 Thymeleaf 속성
th:each | 반복 하려는 html 엘리먼트에 사용하여 콜렉션(Collection)을 반복 한다. th:each="콜렉션 변수명, status 변수면 : ${리스트}" |
th:with | 변수형태의 값을 재정의 thLwith=변수명=${data} |
th:text | document 객체에 텍스트를 삽입 th:text=${data} |
th:href | href에 값을 삽입할 때 사용 th:href=@{URL(파라미터명=${data})} |
th:value | value에 값을 삽입할 때 사용 th:value=${data} |
'프로젝트 > 게시판' 카테고리의 다른 글
V2 - 게시판 만들기(초기 설정)#1 (0) | 2022.09.05 |
---|---|
V1 - 수정, 삭제 구현하기 (0) | 2022.09.05 |
V1 - 테스트 코드 작성 (0) | 2022.08.27 |
V1 - JPA CRUD, MySQL (0) | 2022.08.25 |
V1 - Spring Boot 게시판 만들기 설정 (0) | 2022.08.25 |