원본 영상 링크:
https://www.youtube.com/watch?v=Y7S1xXsKy_w&list=PLZzruF3-_clsWF2aULPsUPomgolJ-idGJ&index=8
페이징 처리 1
localhost:8080/board/list?page=1&size=10
첫페이지는 0페이지부터 시작한다.
controller > BoardController.java
package com.example.demo.contoller;
import com.example.demo.entity.testboard;
import com.example.demo.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@Controller
public class BoardContoller {
@Autowired
private BoardService boardService;
@GetMapping("/board/write") //어떤 url로 접근할 것인지 정해주는 어노테이션 //localhost:8080/board/write
public String boardWriteForm() {
return "boardwrite";
}
@PostMapping("/board/writepro")
public String boardWritePro(testboard board, Model model, MultipartFile file)throws Exception{
boardService.write(board, file);
model.addAttribute("message","글작성이 완료되었습니다");
model.addAttribute("searchUrl","/board/list");
return "message";
}
/*페이징1*/
@GetMapping("/board/list")
public String boardList(Model model,
/*page : default페이지, size : 한 페이지 게시글수, sort: 정렬기준컬럼, direction : 정렬순서*/
@PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC)
Pageable pageable){
//BoardService에서 만들어준 boardList가 반환되는데, list라는 이름으로 받아서 넘기겠다는 뜻
model.addAttribute("list" , boardService.boardList(pageable)); /*pageable넘기기*/
return "boardList";
}
@GetMapping("/board/view") //localhost:8080/board/view?id=1 //(get방식 파라미터)
public String boardView(Model model, Integer id){
model.addAttribute("testboard", boardService.boardview(id));
return "boardview";
}
@GetMapping("/board/delete")
public String boardDelete(Integer id){
boardService.boardDelete(id);
//게시물삭제하고 게시물리스트로 넘어가야하므로
return "redirect:/board/list";
}
//PathVariable이라는 것은 modify 뒤에있는 {id}부분이 인식이되서 Integer형태의 id로 들어온다는것
@GetMapping("/board/modify/{id}")
public String boardModify(@PathVariable("id") Integer id, Model model){
//상세페이지에 있는 내용과, 수정페이지의 내용이 같기때문에 위 코드와 같은 것을 확인할수있다
model.addAttribute("testboard", boardService.boardview(id));
return "boardmodify";
}
@PostMapping("/board/update/{id}")
public String boardUpdate(@PathVariable("id") Integer id, testboard board, MultipartFile file)throws Exception {
//기존에있던글이 담겨져서온다.
testboard boardTemp = boardService.boardview(id);
//기존에있던 내용을 새로운 내용으로 덮어씌운다.
boardTemp.setTitle(board.getTitle());
boardTemp.setContent(board.getContent());
boardService.write(boardTemp, file); //추가 → 수정한내용을 boardService의 write부분에 넣기
return "redirect:/board/list";
}
}
@GetMapping("/board/list")
public String boardList(Model model,
@PageableDefault (page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC)
Pageable pageable){
BoardService에서 만들어준 boardList가 반환되는데, list라는 이름으로 받아서 넘기겠다는 뜻 model.addAttribute("list" , boardService.boardList(pageable));
return "boardList"; }
page : default페이지 / size : 한 페이지 게시글수 / sort: 정렬기준컬럼 / direction : 정렬순서
service > BoardService.java
package com.example.demo.service;
import com.example.demo.entity.testboard;
import com.example.demo.repository.BoardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;//추가
import java.util.List;
import java.util.UUID;
@Service
public class BoardService {
@Autowired //new를 써야하지만, 스프링부트가 알아서 읽어와서 주입을해준다.
private BoardRepository boardRepository;
//글작성처리
public void write(testboard board , MultipartFile file) throws Exception{
//우리의 프로젝트경로를 담아주게 된다 - 저장할 경로를 지정
String projectPath = System.getProperty("user.dir") + "\\src\\main\\resources\\static\\files";
//식별자 . 랜덤으로 이름 만들어줌
UUID uuid = UUID.randomUUID();
//랜덤식별자_원래파일이름 = 저장될 파일이름 지정
String fileName = uuid + "_" + file.getOriginalFilename();
//File을 생성할건데, 이름은 "name" 으로할거고, projectPath 라는 경로에 담긴다는 뜻
File saveFile = new File(projectPath, fileName);
file.transferTo(saveFile);
board.setFilename(fileName);//디비에 파일 넣기
board.setFilepath("/files/" + fileName); //저장되는 경로
//파일 저장
boardRepository.save(board);
}
//게시글리스트처리 /*페이징 2 : pageble 넘겨주기*/
public Page<testboard> boardList(Pageable pageable){
//findAll : 테스트보드라는 클래스가 담긴 List를 반환하는것을 확인할수있다
return boardRepository.findAll(pageable);
}
//특정 게시글 불러오기
public testboard boardview(Integer id){
return boardRepository.findById(id).get(); //어떤게시글을 불러올지 지정을해주어야한다 (Integer값으로)
}
//특정게시글삭제
public void boardDelete(Integer id){ /*id값 1번을 넣어주면 1번을 삭제한다*/
boardRepository.deleteById(id);
}
}
게시글리스트처리
public Page<testboard> boardList(Pageable pageable){
*findAll : 테스트보드라는 클래스가 담긴 List를 반환하는것을 확인할수있다
return boardRepository.findAll(pageable); }
JPA의 findAll()이라는 메소드를 사용할때 Pageable 이라는 클래스를 넘겨주면 어려운 처리를 간단하게 할 수있게 된다.
오름차순(ASC)이나 내림차순(DESC)
findAll() 이라는 메소드를 통해 DB에있는 모든 정보들을 가져오게되고,
Pageable 이라는 클래스를 넘겨주게되면 그 안에 페이지가 몇페이지인지,
그리고 한페이지에 보여줄 게시글이 몇개인지를 담아서 보내줄수가 있다.
@PageableDefault 어노테이션을 이용해서 기본적인 설정을 해줄수있다.
page=0이 1페이지이다.(default =0)
page=1을 입력하면 2페이지를 보여주는 것을 확인할수있다.
size로 숫자를 설정해주면,입력갯수만큼만 글을 보여준다
페이징 처리 2
필요한 변수
nowPage → 현재페이지
startPage → 블럭에서 보여줄 시작 페이지
endPage → 블럭에서 보여줄 마지막 페이지
타임리프 문법
th:text → 태그 안에 데이터를 출력
th:each → 반목문
th:each = "${number : # number(시작번호, 끝번호)}" → 시작번호에서 끝번호까지 반복
controller > BoardController.java
package com.example.demo.contoller;
import com.example.demo.entity.testboard;
import com.example.demo.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@Controller
public class BoardContoller {
@Autowired
private BoardService boardService;
@GetMapping("/board/write") //어떤 url로 접근할 것인지 정해주는 어노테이션 //localhost:8080/board/write
public String boardWriteForm() {
return "boardwrite";
}
@PostMapping("/board/writepro")
public String boardWritePro(testboard board, Model model, MultipartFile file)throws Exception{
boardService.write(board, file);
model.addAttribute("message","글작성이 완료되었습니다");
model.addAttribute("searchUrl","/board/list");
return "message";
}
/*페이징1*/
@GetMapping("/board/list")
public String boardList(Model model,
/*page : default페이지, size : 한 페이지 게시글수, sort: 정렬기준컬럼, direction : 정렬순서*/
@PageableDefault(page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC)
Pageable pageable){
/*페이징3*/
Page<testboard> list = boardService.boardList(pageable);
int nowPage = list.getPageable().getPageNumber() + 1; /*pageable에서 넘어온 현재페이지를 가지고올수있다*//*0부터시작하니까 +1*/
int startPage = Math.max(nowPage - 4, 1); /*매개변수로 들어온 두 값을 비교해서 큰값을 반환 (1일때, -3이되면 안되니까)*/
int endPage = Math.min(nowPage + 5, list.getTotalPages()); /*마지막 페이지를 초과하면안되니까 이것도 min으로 처리*/
//BoardService에서 만들어준 boardList가 반환되는데, list라는 이름으로 받아서 넘기겠다는 뜻
model.addAttribute("list" , list);
model.addAttribute("nowPage", nowPage);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
return "boardList";
}
@GetMapping("/board/view") //localhost:8080/board/view?id=1 //(get방식 파라미터)
public String boardView(Model model, Integer id){
model.addAttribute("testboard", boardService.boardview(id));
return "boardview";
}
@GetMapping("/board/delete")
public String boardDelete(Integer id){
boardService.boardDelete(id);
//게시물삭제하고 게시물리스트로 넘어가야하므로
return "redirect:/board/list";
}
//PathVariable이라는 것은 modify 뒤에있는 {id}부분이 인식이되서 Integer형태의 id로 들어온다는것
@GetMapping("/board/modify/{id}")
public String boardModify(@PathVariable("id") Integer id, Model model){
//상세페이지에 있는 내용과, 수정페이지의 내용이 같기때문에 위 코드와 같은 것을 확인할수있다
model.addAttribute("testboard", boardService.boardview(id));
return "boardmodify";
}
@PostMapping("/board/update/{id}")
public String boardUpdate(@PathVariable("id") Integer id, testboard board, MultipartFile file)throws Exception {
//기존에있던글이 담겨져서온다.
testboard boardTemp = boardService.boardview(id);
//기존에있던 내용을 새로운 내용으로 덮어씌운다.
boardTemp.setTitle(board.getTitle());
boardTemp.setContent(board.getContent());
boardService.write(boardTemp, file); //추가 → 수정한내용을 boardService의 write부분에 넣기
return "redirect:/board/list";
}
}
Page<testboard> list = boardService.boardList(pageable);
int nowPage = list.getPageable().getPageNumber() + 1;
pageable에서 넘어온 현재페이지를 가지고올수있다 *0부터시작하니까 +1
int startPage = Math.max(nowPage - 4, 1);
Math.max - 매개변수로 들어온 두 값을 비교해서 큰값을 반환 (1일때, -3이되면 안되니까)
int endPage = Math.min(nowPage + 5, list.getTotalPages());
마지막 페이지를 초과하면안되니까 Math.min으로 처리
templates > boardList.html
<!--//2번-->
<!DOCTYPE html>
<html lang="en" xmlns:th="//www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>게시물 리스트 페이지</title>
</head>
<style>
.layout{
width : 500px;
margin : 0 auto;
margin-top: 40px;
} /*layout 하위에 있는 input태그 스타일 설정*/
</style>
<body>
<div class="layout">
<table>
<thead>
<tr>
<th>글번호</th>
<th>제목</th>
</tr>
</thead>
<tbody>
<!--list에 testboard가 담겨있는것을 하나씩 빼준다-->
<tr th:each="testboard : ${list}">
<td th:text="${testboard.id}">1</td>
<td><!--list와 상세 연결-->
<!--href a태그에 링크를 걸어주는역할 --> <!--localhost:8080/board/view?id=board.id-->
<a th:text="${testboard.title}" th:href="@{/board/view(id=${testboard.id})}"></a>
<!--제목입니다-->
</td>
</tr>
</td>
</tbody>
</table>
<!--페이징4-->
<!--굳이 태그로 감쌀필요가없는 부분을 타임리프 문법을 사용할때 쓰는 문법 th:block-->
<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>
</div>
</body>
</html>
th:block 굳이 태그로 감쌀필요가없는 부분을 타임리프 문법을 사용할때 쓰는 문법
'STUDY > SpringBoot' 카테고리의 다른 글
[SpringBoot] 스프링(Spring), 스프링부트(SpringBoot) 차이점 정리✔ (0) | 2022.08.16 |
---|---|
[Springboot] 게시판따라하기(8) - 검색 기능 ✔정리 (0) | 2022.08.10 |
[SpringBoot] 22-08-10 스프링부트 설정 설명 ☑ (0) | 2022.08.10 |
[Springboot] 게시판따라하기(6) - 게시판 파일업로드 ✔정리 (0) | 2022.08.10 |
[StringBoot] Thymeleaf 사용법 정리✔ (0) | 2022.08.10 |