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
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 |
---|
댓글