본문 바로가기
Dev/[프로젝트] 2024 마이펫로그

페이지네이션 미적용 원인 이슈

by javapp 자바앱 2024. 5. 16.
728x90

페이지네이션 미적용 원인 이슈

 

 

 

페이지네이션 미적용 원인

GET /notifications?page=0&size=5

    public Page<NotificationResponse> displayNotifications(User user, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<NotificationDto> notificationDtoPage = notificationQuerydslRepository.findAllByReceiverId(user, pageable);

        return toResponsePage(notificationDtoPage);
    }

 

 

 

public Page<NotificationDto> findAllByReceiverId(User receiver, Pageable pageable) {
    LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);

    List<NotificationDto> notificationDtoList = queryFactory.select(Projections.fields(
                    NotificationDto.class,
                    notification.id,
                    notification.type,
                    notification.message,
                    notification.isRead,
                    notification.createdAt,
                    user.thumbnailPath.coalesce(user.profilePath).as("thumbnailPath")
            ))
            .from(notification)
            .where(receiverContains(receiver)
                .and(notification.createdAt.goe(thirtyDaysAgo)))
            .innerJoin(user).on(notification.actorId.eq(user.id))
            .orderBy(createOrderSpecifier())
            .fetch();
    return new PageImpl<>(notificationDtoList, pageable, notificationDtoList.size());
}

 

 

 

페이지네이션이 적용된 줄 알았어요

        .offset(pageable.getOffset())   // (2) 페이지 번호
        .limit(pageable.getPageSize())  // (3) 페이지 사이즈
        .fetch();

offset과 limit을 추가하고

 

    Long count = getCount(condition);
    return new PageImpl<>(notificationDtoList, pageable, count);

count 도 따로 구해줘야 됩니다.

 

 

 

 

 

 

페이지네이션

평균 25~28

public Page<NotificationDto> findAllByReceiverId(User receiver, Pageable pageable) {
    List<NotificationDto> notificationDtos = getNotificationDts(receiver, pageable);

    Long count = getCount(receiver);

    return new PageImpl<>(notificationDtos, pageable, count);
}

private List<NotificationDto> getNotificationDtos(User receiver, Pageable pageable) {
    LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);

    return queryFactory.select(Projections.fields(
                    NotificationDto.class,
                    notification.id,
                    notification.type,
                    notification.message,
                    notification.isRead,
                    notification.createdAt,
                    user.thumbnailPath.coalesce(user.profilePath).as("thumbnailPath")
            ))
            .from(notification)
            .where(receiverContains(receiver)
                    .and(notification.createdAt.goe(thirtyDaysAgo)))
            .innerJoin(user).on(notification.actorId.eq(user.id))
            .orderBy(createOrderSpecifier())
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            .fetch();
}

private Long getCount(User receiver) {
    LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);

    return queryFactory
            .select(notification.count())
            .from(notification)
            .where(receiverContains(receiver)
                    .and(notification.createdAt.goe(thirtyDaysAgo)))
            .innerJoin(user).on(notification.actorId.eq(user.id))
            .fetchOne();
}

private BooleanExpression receiverContains(User receiver) {
    return notification.receiverId.eq(receiver.getId());
}

private OrderSpecifier[] createOrderSpecifier() {
    List<OrderSpecifier> orderSpecifiers = new ArrayList<>();

    orderSpecifiers.add(new OrderSpecifier(Order.ASC, notification.isRead));
    orderSpecifiers.add(new OrderSpecifier(Order.DESC, notification.createdAt));
    return orderSpecifiers.toArray(new OrderSpecifier[orderSpecifiers.size()]);
}

 

 

그리고 조회 속도 향상을 위해 인덱스를 설정해줍니다.

 

 

Index 가 PK 에만 있을 때

 

 

 

 


Index
: createdAt ASC, PK -- 21.86

Index: createdAt DESC, PK -- 17.81

Index: createdAt, PK createdAt DESC, PK

 

 

 

Pageable 객체로 바인딩

 

컨트롤러 

@GetMapping("/v1/notifications")
public Page<NotificationResponse> displayNotifications(
        @AuthenticationPrincipal PrincipalDetails principalDetails,
        @RequestParam(required = false, defaultValue = "0") int page,
        @RequestParam(required = false, defaultValue = "20") int size) {
    return notificationService.displayNotifications(principalDetails.getUser(), page, size);
}

page, size 각각 사용한 경우

 

@GetMapping("/v2/members")
public Page<MemberTeamDto> searchMemberV2(MemberSearchCondition condition, Pageable pageable) {
    return memberRepository.searchPageComplex(condition, pageable); // 바인딩 된다 page, size, sort
}

pageable 사용

 

 

'Dev > [프로젝트] 2024 마이펫로그' 카테고리의 다른 글

2024 마이펫로그 프로젝트 회고  (0) 2024.04.03

댓글