본문 바로가기
Backend/Spring

[Spring/Java] JPQL & Slice 객체(paging)이용하여 특정 조건의 게시물을 특정 방식으로 가져오기

by persi0815 2024. 7. 7.

Paging과 Slice 객체에 대해서 궁금하다면 이전 글을 보고오면 좋을 것 같다.

https://persi0815.tistory.com/25

 

[Spring/Java] Paging이란? Page 객체 vs Slice 객체 (+ 코드)

1. Paging이란? Paging은 대량의 데이터를 효율적으로 처리하고 사용자에게 필요한 양만큼씩 나누어 제공하는 기법이다. 데이터베이스 쿼리에서 페이징을 구현하면, 전체 데이터 집합을 작은 부분

persi0815.tistory.com

 

1. 북마크한 게시물들을 특정 종류(type)과 정렬 방식(way)에 따라 목록 조회

Controller

@Operation(summary = "북마크 한 전체 게시판 목록 정보 조회 메서드", description = "북마크 한 게시판 중 type, way에 따라 목록을 조회하는 메서드입니다.")
@ApiResponses(value = {
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "BOARD_2005", description = "게시판 목록 조회가 완료되었습니다.")
})
@Parameters({
        @Parameter(name = "type", description = "조회하고 싶은 게시물 타입, EMOTION: 감정, ACTIVITY: 봉사, CHAT: 잡담, ALL: 전체"),
        @Parameter(name = "way", description = "정렬 방식,  like: 좋아요순, time: 최신순"),
        @Parameter(name = "scrollPosition", description = "데이터 가져올 시작 위치. 0부터 시작. scrollPosition * fetchSize가 첫 데이터 주소"),
        @Parameter(name = "fetchSize", description = "가져올 데이터 크기(게시물 개수)")
})
@GetMapping("/list/bookmark")
public ApiResponse<BoardListResDto> getBookmarkBoards(
        @AuthenticationPrincipal CustomUserDetails customUserDetails,
        @RequestParam(name = "type") String type,
        @RequestParam(name = "way") String way,
        @RequestParam(name = "scrollPosition", defaultValue = "0") int scrollPosition,
        @RequestParam(name = "fetchSize", defaultValue = "1000") int fetchSize
){
    User user = userService.findUserByUserName(customUserDetails.getUsername());
    BoardType boardType = BoardType.valueOf(type);
    List<Board> bookmarkBoards = boardService.getBookmarkBoardList(user, boardType, way, scrollPosition, fetchSize);
    return ApiResponse.onSuccess(SuccessCode.BOARD_LIST_VIEW_SUCCESS, BoardConverter.boardListResDto(bookmarkBoards));
}

 

Service

public List<Board> getBookmarkBoardList(User user, BoardType boardType, String way, int scrollPosition, int fetchSize) {
    Long userId = user.getId();
    Slice<Board> boardSlice = boardRepository.findBookmarkByUserIdAndBoardTypeAndWay(userId, boardType, way, PageRequest.of(scrollPosition, fetchSize));
    return boardSlice.getContent();
}

 

Repository

@Query("SELECT b FROM Board b JOIN b.bookmarkList bm WHERE bm.user.id = :userId AND (:boardType = 'ALL' OR b.boardType = :boardType) ORDER BY " +
        "CASE WHEN :way = 'like' THEN b.likeCount END DESC, " +
        "CASE WHEN :way = 'like' THEN b.createdAt END DESC, " +
        "CASE WHEN :way = 'time' THEN b.createdAt END DESC")
Slice<Board> findBookmarkByUserIdAndBoardTypeAndWay(@Param("userId") Long userId, @Param("boardType") BoardType boardType, @Param("way") String way, Pageable pageable);

 

2. 내가 작성한 게시물들을 특정 종류(type)과 정렬 방식(way)에 따라 목록 조회

Controller

@Operation(summary = "내가 작성한 전체 게시판 목록 정보 조회 메서드", description = "내가 작성한 게시판 중 type, way에 따라 목록을 조회하는 메서드입니다.")
@ApiResponses(value = {
        @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "BOARD_2005", description = "게시판 목록 조회가 완료되었습니다.")
})
@Parameters({
        @Parameter(name = "type", description = "조회하고 싶은 게시물 타입, EMOTION: 감정, ACTIVITY: 봉사, CHAT: 잡담, ALL: 전체"),
        @Parameter(name = "way", description = "정렬 방식,  like: 좋아요순, time: 최신순"),
        @Parameter(name = "scrollPosition", description = "데이터 가져올 시작 위치. 0부터 시작. scrollPosition * fetchSize가 첫 데이터 주소"),
        @Parameter(name = "fetchSize", description = "가져올 데이터 크기(게시물 개수)")
})
@GetMapping("/list/my")
public ApiResponse<BoardListResDto> getMyBoards(
        @AuthenticationPrincipal CustomUserDetails customUserDetails,
        @RequestParam(name = "type") String type,
        @RequestParam(name = "way") String way,
        @RequestParam(name = "scrollPosition", defaultValue = "0") int scrollPosition,
        @RequestParam(name = "fetchSize", defaultValue = "1000") int fetchSize
){
    User user = userService.findUserByUserName(customUserDetails.getUsername());
    BoardType boardType = BoardType.valueOf(type);
    List<Board> myBoards = boardService.getMyBoardList(user, boardType, way, scrollPosition, fetchSize);
    return ApiResponse.onSuccess(SuccessCode.BOARD_LIST_VIEW_SUCCESS, BoardConverter.boardListResDto(myBoards));
}

 

Service

public List<Board> getMyBoardList(User user, BoardType boardType, String way, int scrollPosition, int fetchSize) {
    Long userId = user.getId();
    Slice<Board> boardSlice = boardRepository.findMyByUserIdAndBoardTypeAndWay(userId, boardType, way, PageRequest.of(scrollPosition, fetchSize));
    return boardSlice.getContent();
}

 

Repository

@Query("SELECT b FROM Board b WHERE b.user.id = :userId AND (:boardType = 'ALL' OR b.boardType = :boardType) ORDER BY " +
        "CASE WHEN :way = 'like' THEN b.likeCount END DESC, " +
        "CASE WHEN :way = 'like' THEN b.createdAt END DESC, " +
        "CASE WHEN :way = 'time' THEN b.createdAt END DESC")
Slice<Board> findMyByUserIdAndBoardTypeAndWay(@Param("userId") Long userId, @Param("boardType") BoardType boardType, @Param("way") String way, Pageable pageable);