일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- javascript
- StyleSheet
- security
- 시큐리티
- 소스트리
- gradle
- sql
- 목록
- input태그
- 반복문
- 싱글톤
- java
- 2차원배열
- 시큐리티 로그아웃
- springboot
- 로그인
- html
- 스프링 부트
- 프로그래머스
- Spring boot
- 시큐리티로그인
- css
- 리눅스
- programmers
- Linux
- codingtest
- 시큐리티 로그인
- 코딩테스트
- JAVA11
- springSecurity
Archives
- Today
- Total
JAVAIARY
Spring Boot) 목록처리 본문
- 고려사항
- 화면에서 필요한 목록 데이터에 대한 DTO 생성
- DTO를 Pageable 타입으로 전환
- Page<Entity>를 화면에서 사용하기 쉬운 DTO의 리스트 등으로 변환
- 화면에 필요한 페이지 번호 처리
1. 목록 처리를 위한 DTO
- PageRequestDTO: 목록 페이지를 요청할 때 사용하는 데이터를 재사용하기 쉽게 만드는 클래스
package com.example.demo.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@Builder
@AllArgsConstructor
@Data
public class PageRequestDTO {
private int page;
private int size;
public PageRequestDTO(){
this.page = 1;
this.size = 10;
}
public Pageable getPageable(Sort sort){
return PageRequest.of(page -1, size, sort);
}
}
2. 페이지 결과 처리
2-1. PageResultDTO 생성
- Repository 에서는 페이지 처리 결과를 Page<Entity> 타입으로 반환
- 따라서 Page<Entity>의 엔티티 객체들을 DTO객체로 변환해서 자료구조로 담아주어야 함
- 화면출력에 필요한 페이지 정보들을 구성해 주어야 함
PageResultDTO
package com.example.demo.dto;
import lombok.Data;
import org.springframework.data.domain.Page;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
public class PageResultDTO<DTO, EN> { //DTO와 Entity 타입으로 지정
private List<DTO> dtoList;
public PageResultDTO(Page<EN> result, Function<EN, DTO> fn){
dtoList = result.stream().map(fn).collect(Collectors.toList());
}
}
- Function<EN, DTO> : 엔티티 객체들을 DTO로 변환해 주는 기능
2-2. GuestbookService 인터페이스에 메서드 추가
- PageRequestDTO를 파라미터로, PageResultDTO를 리턴타입으로 사용하는 getList() 정의
- 엔티티 객체를 DTO 객체로 변환하는 entityToDTO() 정의
PageResultDTO<GuestbookDTO, Guestbook> getList(PageRequestDTO requestDTO);
default GuestbookDTO entityToDTO(Guestbook entity){
GuestbookDTO dto = GuestbookDTO.builder()
.gno(entity.getGno())
.title(entity.getTitle())
.content(entity.getContent())
.writer(entity.getWriter())
.regDate(entity.getRegDate())
.modDate(entity.getModDate())
.build();
return dto;
}
2-3. GuestbookServiceImpl에서 getList() 구현
@Override
public PageResultDTO<GuestbookDTO, Guestbook> getList(PageRequestDTO requestDTO) {
Pageable pageable = requestDTO.getPageable(Sort.by("gno").descending());
Page<Guestbook> result = repository.findAll(pageable);
Function<Guestbook, GuestbookDTO> fn = (entity ->
entityToDTO(entity));
return new PageResultDTO<>(result, fn);
}
- entityToDTO()를 이용해서 java.util.Function을 생성하고 이를 PageResultDTO
Tests: 목록 처리 테스트
엔티티 객체가 DTO 객체로 변환되었는지 확인
@Test
public void testList(){
PageRequestDTO pageRequestDTO = PageRequestDTO.builder().page(1).size(10).build();
PageResultDTO<GuestbookDTO, Guestbook> resultDTO = service.getList(pageRequestDTO);
for(GuestbookDTO guestbookDTO : resultDTO.getDtoList()){
System.out.println(guestbookDTO);
}
}
- GuestbookDTO 타입으로 출력되는 것 확인
2-4. 목록 데이터 페이지 처리 : PageResultDTO
페이징 처리 구성 요소
start | 화면에서 시작 페이지 번호 |
end | 화면에서 끝 페이지 번호 |
prev, next | 이전/다음 이동 링크 여부 |
page | 현재 페이지 번호 |
package com.example.demo.dto;
import lombok.Data;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Data
public class PageResultDTO<DTO, EN> { //DTO와 Entity 타입으로 지정
// DTO 리스트
private List<DTO> dtoList;
//총 페이지 번호
private int totalPage;
//현재 페이지 번호
private int page;
//목록 사이즈
private int size;
//시작 페이지 번호, 끝 페이지 번호
private int start, end;
// 이전, 다음
private boolean prev, next;
//페이지 번호 목록
private List<Integer> pageList;
public PageResultDTO(Page<EN> result, Function<EN, DTO> fn){ //function:엔티티 객체들을 DTO로 변환해 주는 기능
dtoList = result.stream().map(fn).collect(Collectors.toList());
totalPage = result.getTotalPages();
makePageList(result.getPageable());
}
private void makePageList(Pageable pageable) {
this.page = pageable.getPageNumber() + 1 ; // 0부터 시작하므로 1을 추가
this.size = pageable.getPageSize();
// temp end page
int tempEnd = (int)(Math.ceil(page/10.0))*10;
start = tempEnd -9;
prev = start > 1;
end = totalPage > tempEnd ? tempEnd : totalPage; // tempEnd와 totalPage 비교 후 더 작은값 사용
next = totalPage > tempEnd;
pageList = IntStream.rangeClosed(start, end).boxed().collect(Collectors.toList());
}
}
- prev, next 는 boolean 값이므로 조건식으로 참, 거짓 판별하여 넣어줌
Tests : GuestbookServiceTests - testList() 수정
public void testList(){
PageRequestDTO pageRequestDTO = PageRequestDTO.builder().page(1).size(10).build();
PageResultDTO<GuestbookDTO, Guestbook> resultDTO = service.getList(pageRequestDTO);
System.out.println("PREV : " + resultDTO.isPrev());
System.out.println("NEXT : " + resultDTO.isNext());
System.out.println("TOTAL : " + resultDTO.getTotalPage());
System.out.println("-----------------------------------------");
for (GuestbookDTO guestbookDTO : resultDTO.getDtoList()){
System.out.println(guestbookDTO);
}
System.out.println("=========================================");
resultDTO.getPageList().forEach(i -> System.out.println(i));
}
- 최신순으로 gno 301번부터 10개 출력
3. 컨트롤러와 화면에서의 목록처리
3-1. controller 와 html 작성
GuestbookController
package com.example.demo.controller;
import com.example.demo.dto.PageRequestDTO;
import com.example.demo.entity.Guestbook;
import com.example.demo.service.GuestbookService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/guestbook")
@Log4j2
@RequiredArgsConstructor // 자동주입을 위한 Annotation
public class GuestbookController {
private final GuestbookService service; // final로 선언
public String index(){
return "redirect:/guestbook/list";
}
@GetMapping("/list")
public void list(PageRequestDTO pageRequestDTO, Model model){
log.info("----------------" + pageRequestDTO);
model.addAttribute("result", service.getList(pageRequestDTO));
}
}
- 자동주입을 위한 @RequiredArgsConstructor 어노테이션 추가
- GuestbookService 변수 추가
- list() 추가
- Spring MVC 는 파라미터를 자동으로 수집해 주는 기능이 있으므로, 화면에서 page와 size라는 파라미터를 전달하면 PageRequestDTO 객체로 자동으로 수집됨
- Model은 결과 데이터를 화면에 전달하기 위해 사용
list.html 작성
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<th:block th:replace="~{/layout/basic :: setContent(~{this::content} )}">
<th:block th:fragment="content">
<h1 class="mt-4">GuestBook List Page</h1>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">No.</th>
<th scope="col">Gno</th>
<th scope="col">Title</th>
<th scope="col">Regdate</th>
</tr>
</thead>
<tbody>
<tr th:each="dto : ${result.dtoList}">
<th scope="row">[[${dto.gno}]]</th>
<td>[[${dto.title}]]</td>
<td>[[${dto.writer}]]</td>
<td>[[${#temporals.format(dto.regDate,'yyyy/MM/dd')}]]</td>
</tr>
</tbody>
</table>
<ul class="pagination h-100 justify-content-center align-items-center">
<li class="page-item " th:if="${result.prev}">
<a class="page-link" href="#" tabindex="-1">Previous</a>
</li>
<li th:class=" 'page-item ' + ${result.page == page ? 'active' : ''}" th:each="page: ${result.pageList}">
<a class="page-link" href="#">[[${page}]]</a>
</li>
<li class="page-item " th:if="result.next">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</th:block>
</th:block>
</html>
- 목록 출력 확인
3-2. 페이지 번호 링크 처리
- th:href 를 이용하여 작성
<ul class="pagination h-100 justify-content-center align-items-center">
<li class="page-item " th:if="${result.prev}">
<a class="page-link" th:href="@{/guestbook/list(page= ${result.start -1})}" tabindex="-1">Previous</a>
</li>
<li th:class=" 'page-item ' + ${result.page == page ? 'active' : ''}" th:each="page: ${result.pageList}">
<a class="page-link" th:href="@{/guestbook/list(page= ${page})}">[[${page}]]</a>
</li>
<li class="page-item " th:if="${result.next}">
<a class="page-link" th:href="@{/guestbook/list(page= ${result.end + 1})}">Next</a>
</li>
</ul>
'Project > 2023.02~ ) Study toy 프로젝트' 카테고리의 다른 글
N:1(다대일) 연관관계 1 (0) | 2023.03.01 |
---|---|
검색 처리 (0) | 2023.02.27 |
Spring Boot) 게시글 수정/ 삭제 처리 (0) | 2023.02.21 |
Spring Boot) 게시글 등록 페이지 / 등록 처리 (0) | 2023.02.20 |
Spring Boot) 서비스 계층과 DTO (0) | 2023.02.20 |