티스토리 뷰

728x90

특정 페이지에 들어 갔을때 랜덤하게 데이터를 구성하고자 했다.(like 로또)

Querydsl과 페이징 처리 되어 있는 조건으로 구글링을 해보는데 예제가 많이 없고,

현재 버전에서는 제공하지 않는 utils들을 활용하는 글들이 대부분이라 해당 글을 작성하게 되었다. 

 

 

 

로직


Controller

@ApiOperation(value = "(팀 찾기) 팀 리스트 가져오기", notes = "팀 이름 혹은 팀 고유번호를 입력해야한다. ")
@GetMapping("/teams")
public CommonResponse<?> teams (@RequestParam int pageNum,
                                @RequestParam int pageSize,
                                @RequestParam String pageSort
                                ) {
    return teamService.getTeams(pageNum, pageSize, pageSort);
}

 

pageNum: 시작페이지수

pageSize: 들고올 데이터  수

 

ex)

pageNum: 0

pageSize: 10 

일 경우 0~10 까지 총 10개의  데이터를 가져옴 

 

pageNum: 1

pageSize: 10 

일 경우 11~20 까지 총 10개의 데이터를 가져옴 

 

pageSort: 정렬 기준 (DESC, ASC, SHUFFLE)

여기서는 SHUFFLE을 사용한다. 

Service

public CommonResponse<?> getTeams(int pageNum, int pageSize, String pageSort) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
	if (pageSort.equals("SHUFFLE")) {
    Page<TeamSearchDto> teamSearchDtos = teamCustomImpl.getTeamsInfoByDefault(pageable);
    List<TeamSearchDto> content = new ArrayList<>(teamSearchDtos.getContent());
    
    Collections.shuffle(content);
    int fromIndex = (int) pageable.getOffset();
    int toIndex = Math.min(fromIndex + pageable.getPageSize(), content.size());

	log.info("fromIndex:" + fromIndex);
	log.info("pageable.getPageSize():" + pageable.getPageSize());
	log.info("content.size()" + ":" + content.size());
    
    List<TeamSearchDto> subList = content.subList(fromIndex, toIndex);
    return CommonResponse.createSuccess(new PageImpl<>(subList, pageable, content.size()), "팀 랜덤(SHUFFLE) 리스트 success");
}

가장 핵심이 Service 로직이다.

1. 먼저 teamCustomImpl에서 데이터를(*페이징 처리, 정렬 x) 가져온다. 

2. Collections.shuffle()메소드를 활용하여 해당 content를 랜덤하게 섞는다. 

3. 페이징 처리할 데이터를 가공한다.

4. new 연산자를 통해 해당값의 페이징 처리를 진행한다. 

 

 

 

 

CustomImpl

public Page<TeamSearchDto> getTeamsInfoByDefault(Pageable pageable) {
        List<TeamSearchDto> content =  queryFactory.select(new QTeamSearchDto(
                        team.id
                        , team.teamName
                        , team.oneIntro
                        , team.teamSerialNo
                        , member.name
                        , team.memberCount
                        , image.imageUrl
                ))
                .from(teamMemberInfo)
                .join(teamMemberInfo.team, team)
                .leftJoin(team.teamLogo, image)
                .join(teamMemberInfo.member, member)
                .on(teamMemberInfo.authority.eq(AuthorityStatus.valueOf("LEADER")))
//                .offset(pageable.getOffset()) -> service에서 처리한다.
//                .limit(pageable.getPageSize()) -> service에서 처리한다.
                .fetch();

        JPAQuery<Long> countQuery = queryFactory
                .select(teamMemberInfo.count())
                .from(teamMemberInfo)
                .join(teamMemberInfo.team, team)
                .leftJoin(team.teamLogo, image)
                .join(teamMemberInfo.member, member)
                .on(teamMemberInfo.authority.eq(AuthorityStatus.valueOf("LEADER")));


        return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne);
    }

@Queryprojection으로 전달할 데이터를 선언하고

CountQuery를 분리하여PageableExecutionUtils에 값을 담는다(22년도 부턴가 Querydsl의 페이징 처리가 바뀜)

 

보통 Querydsl르 사용하면 customImpl에서 offset과 limit을 설정하지만 여기선 데이터를 가져온 뒤 Service에서  offset, limit 설정을 한다. 

 

그 이유는 customImpl에서 offset, limit 설정을 하면 랜덤하게 섞을 데이터가 전체가 아닌 페이징 처리된 데이터 내에서 Shuffle이 동작하기 때문이다. 

 

 

 

728x90
댓글
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday