초코딩(chocoding)

[Project - 게시판 / spring boot] Querydsl로 board List 출력하기 / 결과값에 의한 Pagination 구현 / QueryResults란? 본문

Project

[Project - 게시판 / spring boot] Querydsl로 board List 출력하기 / 결과값에 의한 Pagination 구현 / QueryResults란?

sweetychocoding 2024. 2. 16. 10:59
728x90

이제 Querydsl로 board list 를 출력해보겠다.

 

먼저 게시판 등록이나 다른 insert되는 기능들을 구현하지 않았기 때문에

직접 db에 mock data 들을 추가해주었다.

 

그리고 service, serviceimpl, jsp 등등 코드를 구현하였다.

 

구현하면서 어려웠던 점은 service에서 selectList 메서드를 구현하는데

리스트들의 반환타입과 기존 팀 프로젝트 때 만들어둔 페이지네이션의 반환타입이 맞지 않아서

꽤나 오랜 시간을 고민했다.

 

그리고 QueryResults 라는 것을 알게 되었다.

 

QueryResults

: QueryDSL에서 제공되는 클래스

: 쿼리 결과를 처리하고 조작하기 위한 유틸리티 클래스 중 하나로 사용

: 쿼리 실행 결과를 감싸고 여러 유용한 메서드를 제공하여 개발자가 쉽게 결과를 처리할 수 있도록 함

 

결국 페이지네이션을 구현한 PageResultDTO에

쿼리문의 결과값과 페이지에 대한 정보를 매개변수로 같이 담아서 반환하는 것으로 구현하였다.

 

 

 

팀 프로젝트 때 이미 JPQL을 사용하여 Pagination을 다 구현해놨던터라

쉽게 구현할 수 있을 줄 알았는데....

 

역시 쉬운 건 1도 없구나,,, 하하

 

 

 

 

 

 

 

 

PageResultDTO

package com.cm.personalProject.domain;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import com.querydsl.core.QueryResults;

import lombok.Data;

@Data
public class PageResultDTO<EN> {
	// => Entity type 지정

	// =>결과 리스트
	private List<EN> entityList;

	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) {

		entityList = result.getContent();
		totalPage = result.getTotalPages();
		makePageList(result.getPageable());

	} // 생성자

	public PageResultDTO(QueryResults<EN> queryResults, Pageable pageable) {
		entityList = queryResults.getResults();
		totalPage = (int) Math.ceil((double) queryResults.getTotal() / pageable.getPageSize());
		makePageList(pageable);
	}

	private void makePageList(Pageable pageable) {

		this.page = pageable.getPageNumber() + 1;
		this.size = pageable.getPageSize();

		int tempEnd = (int) (Math.ceil(page / 10.0)) * 10;

		start = tempEnd - 9;
		end = totalPage > tempEnd ? tempEnd : totalPage;

		prev = start > 1;
		next = totalPage > tempEnd;

		pageList = IntStream.rangeClosed(start, end).boxed().collect(Collectors.toList());
	} // makePageList

} // class

 

 

 

 

 

PageRequestDTO

package com.cm.personalProject.domain;


import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

@Builder
@Data
@AllArgsConstructor
public class PageRequestDTO {
    
    private int page; // 요청받은 PageNo
    private int size; // 1페이지당 출력 row 개수
    
    // ** 기본생성자로 초기화
    public PageRequestDTO() {
        this.page = 1;
        this.size = 10;
    }
    
    public Pageable getPageable() {
        return PageRequest.of(page - 1, size);
    }
    
}

 

 

 

 

 

BoardController

	// List =====================================================
	@GetMapping("/boardPage")
	public void getBoardList(Model model, @RequestParam(value = "page", defaultValue = "1") int page,
			@RequestParam(value = "searchType", defaultValue = "") String searchType,
			@RequestParam(value = "keyword", defaultValue = "") String keyword) {

		PageRequestDTO requestDTO = PageRequestDTO.builder().page(page).size(5).build();
		PageResultDTO<Board> resultDTO = boardService.selectList(requestDTO, searchType, keyword);

		model.addAttribute("selectList", resultDTO.getEntityList());
		model.addAttribute("resultDTO", resultDTO);
		model.addAttribute("searchType", searchType);
		model.addAttribute("keyword", keyword);
		
	}// getBoardList()

 

 

 

 

 

 

BoardService

@Override
	public PageResultDTO<Board> selectList(PageRequestDTO requestDTO, String searchType, String keyword) {
		BooleanExpression searchCondition = getSearchCondition(searchType, keyword);

		QueryResults<Board> result = queryFactory.selectFrom(board)
				.where(board.board_delyn.eq('N').and(searchCondition)).orderBy(board.board_id.desc())
				.offset(requestDTO.getPageable().getOffset()).limit(requestDTO.getPageable().getPageSize())
				.fetchResults();

		return new PageResultDTO<>(result, requestDTO.getPageable());
	}

	private BooleanExpression getSearchCondition(String searchType, String keyword) {
		if ("all".equals(searchType) || "".equals(keyword)) {
			return null;
		}

		switch (searchType) {
		case "useremail":
			return board.useremail.contains(keyword);
		case "board_title":
			return board.board_title.contains(keyword);
		case "board_content":
			return board.board_content.contains(keyword);
		default:
			return null;
		}
	}

 

 

 

 

 

 

다음 step도 팟팅

728x90