게시글 페이징 처리
- 게시글 리스트 요청에 따른 Controller 생성
/
혹은/board/myPost
요청이 오면 요청에 따른 게시글 조회 페이지를 응답할 수 있도록 컨트롤러에 메서드를 생성하고 매핑합니다.
- 게시글 리스트 view 생성
- 게시글은 4개씩 id에 의해 정렬되어 페이징될 것입니다.
- 비즈니스 로직을 담당하는 Service 파일 생성
- 전체 게시글을 조회하는 기능
- 나의 게시글을 조회하는 기능
페이징 처리 기능 구현 전 Pageable 인터페이스에 대해 먼저 알아보려 합니다.
Pageable
Pageable은 Spring Data 프로젝트에서 제공하는 인터페이스 중 하나로, 데이터베이스에서 검색 결과를 페이징 처리할 수 있도록 돕는 인터페이스입니다.
Pageable을 사용하면 검색 결과의 일부분만 가져오거나, 특정 페이지를 조회할 수 있습니다. 이를 통해 대량의 데이터를 처리할 때 성능을 향상시킬 수 있습니다.
Spring Data JPA에서 Pageable을 사용하면 다음과 같이 검색 결과를 페이징 처리할 수 있습니다.
Pageable pageable = PageRequest.of(page, size);
Page<Entity> entities = entityRepository.findAll(pageable);
여기서 page
는 검색 결과에서 가져올 페이지 번호를 나타내며, size
는 페이지당 표시할 항목 수를 나타냅니다. Entity
는 검색 결과의 엔티티 클래스이고, entityRepository
는 엔티티의 레파지토리 클래스입니다. 이렇게 하면 요청한 페이지의 결과가 entities
변수에 저장됩니다.
Pageable 인터페이스는 페이징 처리를 위한 getPageNumber()
, getPageSize()
, getOffset()
, getSort()
등의 메서드를 제공합니다.
프로젝트에서 Pageable을 사용하려면, 페이지별 데이터 요청을 처리하는 컨트롤러를 작성하고, 뷰를 업데이트하여 페이징 된 데이터를 표시하고, 데이터베이스에서 페이징 된 데이터를 검색하는 비즈니스 로직을 처리하는 서비스 클래스를 작성해야 합니다. 또한, 레파지토리에 페이징 처리를 위한 메서드를 추가해야합니다.
Pageable 메서드
Pageable
인터페이스는 다음과 같은 메서드를 제공합니다.
int getPageNumber()
: 현재 페이지 번호를 반환합니다.int getPageSize()
: 페이지당 항목 개수를 반환합니다.long getOffset()
: 현재 페이지의 시작 인덱스를 반환합니다.Sort getSort()
: 정렬 정보를 반환합니다.Pageable next()
: 다음 페이지를 반환합니다.Pageable previousOrFirst()
: 이전 페이지를 반환합니다. 만약 현재 페이지가 첫 페이지라면 첫 페이지를 반환합니다.Pageable first()
: 첫 페이지를 반환합니다.boolean hasPrevious()
: 현재 페이지 이전 페이지가 있는지 여부를 반환합니다.
게시글 리스트 요청에 따른 Controller 생성
“/” 요청의 경우
@GetMapping({"","/"})
public String index(Model model,
@PageableDefault(size = 4,
sort = "id",
direction = Sort.Direction.DESC)
Pageable pageable){
model.addAttribute("boards", boardService.findAll(pageable));
return "index"; // viewResolver 작동
}
메인페이지 요청의 경우 모든 사용자가 모든 게시글을 조회할 수 있도록 구현 합니다.
Pageable
인터페이스를 사용하여 게시글 4개씩 페이징 처리하고, board 정보의 id를 통하여 정렬 처리합니다.
@PageableDefault
어노테이션은 Spring MVC 프레임워크에서 Pageable 파라미터를 처리할 때 사용하는 어노테이션입니다. Pageable 파라미터가 생략되었을 때 기본값을 설정할 수 있습니다.
@PageableDefault
어노테이션에는 다음과 같은 속성이 있습니다.
size
: 한 페이지에 보여줄 항목 수sort
: 정렬 방법direction
: 정렬 방향
boardService
에서 반환된 정보를 model
에 담아 index
페이지를 응답합니다.
"/board/myPost" 요청의 경우
@GetMapping("/board/myPost")
public String myPost(Model model,
@AuthenticationPrincipal PrincipalDetail principalDetail,
@PageableDefault(size = 4,
sort = "id",
direction = Sort.Direction.DESC)
Pageable pageable){
model.addAttribute("boards",
boardService.findAllUserBoard(principalDetail.getUser(), pageable));
return "board/myPost";
}
해당 요청의 경우 로그인된 사용자에 한해 본인의 게시글을 조회할 수 있도록 구현합니다.
스프링 시큐리티 세션에 등록된 사용자 정보를 `BoardService`인터페이스에 전달하고 반환된 정보를 `model`에 담아 `board/myPost` 페이지를 응답합니다.
메인페이지 요청의 경우 모든 사용자가 모든 게시글을 조회할 수 있도록 구현 합니다.
Pageable
인터페이스를 사용하여 게시글 4개씩 페이징 처리하고, board 정보의 id를 통하여 정렬 처리합니다.
@PageableDefault
어노테이션은 Spring MVC 프레임워크에서 Pageable 파라미터를 처리할 때 사용하는 어노테이션입니다. Pageable 파라미터가 생략되었을 때 기본값을 설정할 수 있습니다.
@PageableDefault
어노테이션에는 다음과 같은 속성이 있습니다.
size
: 한 페이지에 보여줄 항목 수sort
: 정렬 방법direction
: 정렬 방향
boardService
에서 반환된 정보를 model
에 담아 index
페이지를 응답합니다.
게시글 리스트 view 생성
게시글 조회 view는 Thymeleaf 템플릿으로 작성되었습니다.
layout.html
/fragment/board/layout.html
<th:block th:fragment="boardLayoutFragment">
<div th:each="board : ${boards}">
<div class="card" style="padding: 1rem; margin-bottom: 1rem">
<div class="card-body">
<h4 class="card-title" th:text="${board.title}">제목 적는 부분</h4>
<a th:href="@{/board/{id}(id = ${board.id})}" class="btn btn-primary">상세 보기</a>
</div>
</div>
</div>
<ul class="pagination justify-content-center" style="margin:20px 0">
<li th:if="${boards.isFirst()}" class="page-item disabled">
<a class="page-link" th:href="@{/(page=${boards.getNumber() - 1 })}">Previous</a>
</li>
<li th:unless="${boards.isFirst()}" class="page-item">
<a class="page-link" th:href="@{/(page=${boards.getNumber() - 1 })}">Previous</a>
</li>
<li th:if="${boards.isLast()}" class="page-item disabled">
<a class="page-link" th:href="@{/(page=${boards.getNumber() + 1 })}">Next</a>
</li>
<li th:unless="${boards.isLast()}" class="page-item">
<a class="page-link" th:href="@{/(page=${boards.getNumber() + 1 })}">Next</a>
</li>
</ul>
</th:block>
전체 게시글 조회, 본인 게시글 조회의 중복되는 코드를 Thymeleaf 템플릿으로 작성해줍니다.
<div th:replace="/fragments/board/layout :: boardLayoutFragment"></div>
이후 위의 코드를 사용하여 각 페이지에 레이아웃을 적용해줍니다.
myPost.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- --------------------- config --------------------- -->
<th:block th:replace="/fragments/config :: configFragment"></th:block>
</head>
<body>
<!-- --------------------- header --------------------- -->
<div th:replace="/fragments/header :: headerFragment"></div>
<div class="container">
<!-- <h1>내가 쓴 글 보기</h1>-->
<div th:replace="/fragments/board/layout :: boardLayoutFragment"></div>
</div>
<!-- --------------------- footer --------------------- -->
<div th:replace="/fragments/footer :: footerFragment"></div>
</body>
</html>
비즈니스 로직을 담당하는 Service 파일 생성
public Page<Board> findAllUserBoard(User user, Pageable pageable){
return boardRepository.findByUser(user, pageable);
}
public Page<Board> findAll(Pageable pageable) {
return boardRepository.findAll(pageable);
}
Spring Data JPA의 Pageable 인터페이스는 데이터베이스에서 검색 결과를 페이지별로 나누어 처리하는 데 도움을 주는 기능입니다. Pageable을 사용하면 검색 결과의 하위 집합이나 특정 페이지를 검색할 수 있어 대량의 데이터를 처리할 때 성능이 향상됩니다.
Spring Data JPA에서 Pageable을 사용하려면 다음과 같은 코드를 사용할 수 있습니다.
Pageable pageable = PageRequest.of(page, size);
Page<Entity> entities = entityRepository.findAll(pageable);
여기서 page
는 검색 결과에서 가져올 페이지 번호를 나타내며, size
는 페이지당 표시할 항목 수를 나타냅니다. Entity
는 검색 결과의 엔티티 클래스이고, entityRepository
는 엔티티의 레파지토리 클래스입니다. 이렇게 하면 요청한 페이지의 결과가 entities
변수에 저장됩니다.
Pageable 인터페이스는 페이징 처리를 위한 getPageNumber()
, getPageSize()
, getOffset()
, getSort()
등의 메서드를 제공합니다.
프로젝트에서 Pageable을 사용하려면, 페이지별 데이터 요청을 처리하는 컨트롤러를 작성하고, 뷰를 업데이트하여 페이징 된 데이터를 표시하고, 데이터베이스에서 페이징 된 데이터를 검색하는 비즈니스 로직을 처리하는 서비스 클래스를 작성해야 합니다. 또한, 레파지토리에 페이징 처리를 위한 메서드를 추가해야합니다.
Spring Data JPA - 레포지토리에 메서드 추가
// BoardRepository에 추가
Page<Board> findByUser(User user, Pageable pageable);
findBy
는 Spring Data JPA에서 사용되는 메서드 네이밍 규칙입니다. 이를 통해 개발자는 매번 사용 사례에 맞는 쿼리를 정의하지 않고도 간결하고 가독성 있는 코드를 작성할 수 있습니다.
예를 들어, name
필드가 있는 User
엔티티가 있다면, findByName
이라는 메서드를 생성하여 이름에 해당하는 모든 사용자를 찾는 쿼리를 자동으로 생성할 수 있습니다.
또한 메서드 네임에서 And
또는 Or
을 사용하여 여러 필드를 조합하여 쿼리를 만들 수도 있습니다. 예를 들어 findByFirstNameAndLastName
는 이름과 성이 모두 일치하는 사용자를 찾습니다.
Spring Data JPA는 Pageable
및 Sort
객체를 사용하여 페이징, 정렬 및 기타 고급 기능도 지원합니다. 이러한 객체는 리포지토리 메서드의 매개변수로 전달하여 쿼리에서 반환되는 결과를 제어할 수 있습니다.
'Spring > 블로그 프로젝트' 카테고리의 다른 글
[Blog 프로젝트] 게시글 삭제 기능 (API 통신) (0) | 2023.03.18 |
---|---|
[Blog 프로젝트] 게시글 상세보기 기능 구현 (0) | 2023.03.18 |
[Blog 프로젝트] 게시글 작성 기능 (API 통신) (0) | 2023.03.18 |
[Blog 프로젝트] 로그인 기능 구현 (스프링 시큐리티) (0) | 2023.03.18 |
[Blog 프로젝트] 회원가입 기능 구현 (0) | 2023.03.18 |