우리는 종종 어떤 검색어를 검색했을 때, 검색 결과가 너무 많으면 여러 페이지로 나누어 결과가 나오는 것을 알 수 있다. 이러한 기법을 페이징
이라고 한다.
JPA
에서는 Page
와 Pageable
, @PageableDefault
를 통해 페이징을 구현할 수 있다.
@GetMapping("/search")
@ResponseBody
public BaseResponse<GetSearchRes> getSearchResults
(@RequestParam(defaultValue = "", require = false) String query,
@PageableDefault(sort = id, direction = sort.Direction.ASC) Pageable pageable)
{
GetSearchRes searchList = searchProvider.retrieveSearch(query, pageable);
return searchList;
}
만약에 /search라는 path에 검색 결과를 불러오고 싶다면 컨트롤러는 위와 같이 작성될 것이다.
쿼리스트링으로 query
, 즉 검색할 문장을 가져올 것이고, Pageable이 들어온다. Pageable
은 Spring JPA에서 DB 쿼리에 쉽고 유연하게 limit 쿼리를 사용하게 해준다.
그리고 @PageableDefault
에서는 정렬 조건을 설정할 수 있다. 한 페이지에 불러 올 데이터의 개수도 설정할 수 있는데, 데이터의 개수를 딱히 설정을 안 하면 한 페이지에 10개 데이터를 가져온다.
그리고 코드에는 나와있지 않지만, Pageable
을 사용하면 쿼리 스트링에 page를 받을 수 있다. 쿼리스트링 page
의 디폴트 값은 0이다. (page는 0부터 시작한다.) 그리고 컨트롤러 코드에 없더라도 &page=3
과 같이 페이지를 지정해서 불러올 수 있다.
public GetSearchRes retrieveSearch(String query, Pageable pageable){
Page<Search> searchPage= searchRepository.findSearchByTitleIsContaining(query, pageable);
List<SearchRes> searchResult = new ArrayList<>();
for(Search search : searchPage) {
searchResult.add(new SearchRes(search.getId(), search.getCreatedAt(), search.getTitle());
}
GetSearchRes searchResultResponse = new GetSearchRes(searchPage.getTotalElements(), searchPage.getTotalPages(), searchResult);
return searchResultResponse;
}
페이징 기법을 하면 레포지토리에서 Page<객체>
형태로 데이터를 가져오게 된다. Pageable의 결과물이 Page
인데 여기에는 잡다한 정보들이 많이 들어가 있으므로 이를 원하는 형태에 맞게 커스텀을 해주면 된다.
Page<Search> findSearchByTitleIsContaining(String query, Pageable pageable);
쿼리문이 제목이 들어가 있는 결과들을 가져올 예정이므로 IsContaining을 사용하고, 페이징을 할 예정이므로 Pageable을 넘겨 페이징을 자동으로 해서 결과들을 불러올 수 있도록 한다.