Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

페이지네이션 처리 시 최대 다음 페이지 수를 5개로 제한 #902

Merged
merged 15 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
d5158ce
refactor(pagination): 고정 페이지네이션에 대한 목록 조회 객체 생성
jminkkk Nov 8, 2024
8b23deb
refactor(response): 고정 페이지네이션에 대한 목록 조회 응답 형식 변경
jminkkk Nov 8, 2024
678d4a0
refactor(pagination): 고정 페이지네이션에 사용되는 페이지 카운팅 객체 구현
jminkkk Nov 8, 2024
5f4c09b
refactor(pagination): 템플릿 목록 조회 시 전체 element 요소 카운트 제거 및 FixedPage 적용
jminkkk Nov 8, 2024
26e2705
refactor: 좋아요한 템플릿 목록 조회에 고정 페이지네이션 적용 및 TemplateRepository로 위치 이
jminkkk Nov 8, 2024
34b7613
Merge branch 'dev/be' into refactor/899-remove-full-pagecount
jminkkk Nov 9, 2024
514f9f1
refactor(pagination): list null 체크 제거
jminkkk Nov 12, 2024
24ab43a
refactor(pagination): @DisplayName 오타 수정
jminkkk Nov 12, 2024
83a6d49
refactor(pagination): 다음페이지가 없는 경우 현재 페이지인 1페이지 반환
jminkkk Nov 12, 2024
01411ff
refactor(repository): 메서드 인자 순서 통일되게 변경
jminkkk Nov 12, 2024
219fa24
refactor(repository): max page를 count하는 메서드명을 명확하 변경
jminkkk Nov 13, 2024
c55cfd2
refactor(template): 목록 조회 응답 시 고정 최대 페이지 변수명 변
jminkkk Nov 13, 2024
6c61b52
refactor(template): 좋아요한 템플릿 조회 Service 메서드 위치 이동
jminkkk Nov 13, 2024
79d8ac1
refactor(repository): query dsl select 라인 줄바
jminkkk Nov 13, 2024
d8d3873
refactor(template): 페이지네이션 페이지 수 응답 변수 이름 변
jminkkk Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package codezap.global.pagination;

import java.util.List;

public record FixedPage<T> (List<T> contents, int nextPages) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package codezap.global.pagination;

import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.jpa.impl.JPAQueryFactory;

@Component
public class FixedPageCounter {

private static final int MAXIMUM_PAGE = 5;
zangsu marked this conversation as resolved.
Show resolved Hide resolved

public int countNextFixedPage(
JPAQueryFactory queryFactory,
EntityPathBase<?> entityPath,
Pageable pageable,
BooleanExpression... conditions
) {
int maximumElementsCount = pageable.getPageSize() * MAXIMUM_PAGE;
long nextFixedElementCounts = queryFactory
.selectFrom(entityPath)
.where(conditions)
.offset(pageable.getOffset())
.limit(maximumElementsCount)
.fetch()
.size();
zangsu marked this conversation as resolved.
Show resolved Hide resolved

return (int) Math.ceil((double) nextFixedElementCounts / pageable.getPageSize());
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package codezap.likes.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import codezap.likes.domain.Likes;
import codezap.member.domain.Member;
Expand All @@ -17,11 +13,4 @@ public interface LikesJpaRepository extends JpaRepository<Likes, Long> {
boolean existsByMemberAndTemplate(Member member, Template template);

long countByTemplate(Template template);

@Query("""
SELECT l.template
FROM Likes l
WHERE l.member.id = :memberId AND (l.template.member.id = :memberId OR l.template.visibility = 'PUBLIC')
""")
Page<Template> findAllByMemberId(@Param(value = "memberId") Long memberId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import codezap.likes.domain.Likes;
Expand Down Expand Up @@ -37,8 +35,4 @@ public void deleteByMemberAndTemplate(Member member, Template template) {
public void deleteAllByTemplateIds(List<Long> templateIds) {
likesQueryDslRepository.deleteAllByTemplateIds(templateIds);
}

public Page<Template> findAllByMemberId(Long memberId, Pageable pageable) {
return likesJpaRepository.findAllByMemberId(memberId, pageable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import codezap.global.pagination.FixedPage;
import codezap.likes.domain.Likes;
import codezap.likes.repository.LikesRepository;
import codezap.member.domain.Member;
Expand Down Expand Up @@ -37,10 +37,6 @@ public boolean isLiked(Member member, Template template) {
return likesRepository.existsByMemberAndTemplate(member, template);
}

public Page<Template> findAllByMemberId(Long memberId, Pageable pageable) {
return likesRepository.findAllByMemberId(memberId, pageable);
}

@Transactional
public void cancelLike(Member member, long templateId) {
Template template = templateRepository.fetchById(templateId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import io.swagger.v3.oas.annotations.media.Schema;

public record FindAllTemplatesResponse(
@Schema(description = "전체 페이지 개수", example = "1")
int totalPages,
@Schema(description = "총 템플릿 개수", example = "134")
long totalElements,
@Schema(description = "최대 페이지 개수, 최대 5개입니다.", example = "1")
int paginationSizes,
@Schema(description = "템플릿 목록")
List<FindAllTemplateItemResponse> templates
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package codezap.template.repository;

import static codezap.template.domain.QTemplate.template;

import java.util.List;
import java.util.Objects;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;

import codezap.global.pagination.FixedPage;
import codezap.global.pagination.FixedPageCounter;
import codezap.likes.domain.QLikes;
import codezap.template.domain.QTemplate;
import codezap.template.domain.Template;
import codezap.template.domain.Visibility;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,8 +22,9 @@ public class TemplateQueryDSLRepository {

private final JPAQueryFactory queryFactory;
private final TemplateSearchExpressionProvider expressionProvider;
private final FixedPageCounter fixedPageCounter;

public Page<Template> findTemplates(
public FixedPage<Template> findTemplates(
Long memberId,
String keyword,
Long categoryId,
Expand All @@ -33,8 +33,8 @@ public Page<Template> findTemplates(
Pageable pageable
) {
List<Template> content = getTemplates(memberId, keyword, categoryId, tagIds, visibility, pageable);
long count = count(memberId, keyword, categoryId, tagIds, visibility);
return new PageImpl<>(content, pageable, count);
int nextFixedPage = countMaxPageOfTemplates(memberId, keyword, categoryId, tagIds, visibility, pageable);
return new FixedPage<>(content, nextFixedPage);
}

private List<Template> getTemplates(
Expand All @@ -45,29 +45,30 @@ private List<Template> getTemplates(
Visibility visibility,
Pageable pageable
) {
return queryFactory
.selectFrom(template)
.leftJoin(template.category).fetchJoin()
.leftJoin(template.member).fetchJoin()
return queryFactory.selectFrom(QTemplate.template)
.leftJoin(QTemplate.template.category).fetchJoin()
.leftJoin(QTemplate.template.member).fetchJoin()
.where(matchesKeyword(memberId, keyword, categoryId, tagIds, visibility))
.orderBy(TemplateOrderSpecifierUtils.getOrderSpecifier(pageable.getSort()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

private long count(
private int countMaxPageOfTemplates(
Long memberId,
String keyword,
Long categoryId,
List<Long> tagIds,
Visibility visibility
Visibility visibility,
Pageable pageable
) {
return Objects.requireNonNull(queryFactory
.select(template.count())
.from(template)
.where(matchesKeyword(memberId, keyword, categoryId, tagIds, visibility))
.fetchOne());
return fixedPageCounter.countNextFixedPage(
queryFactory,
QTemplate.template,
pageable,
matchesKeyword(memberId, keyword, categoryId, tagIds, visibility)
);
}

private BooleanExpression[] matchesKeyword(
Expand All @@ -85,5 +86,34 @@ private BooleanExpression[] matchesKeyword(
expressionProvider.matchesKeyword(keyword)
};
}

public FixedPage<Template> findAllLikedByMemberId(Long memberId, Pageable pageable) {
List<Template> content = queryFactory.select(QLikes.likes.template)
.from(QLikes.likes)
.where(isLikedTemplateByMember(memberId))
.orderBy(TemplateOrderSpecifierUtils.getOrderSpecifier(pageable.getSort()))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();

return new FixedPage<>(content, countMaxPageOfLikeTemplates(memberId, pageable));
}

private int countMaxPageOfLikeTemplates(Long memberId, Pageable pageable) {
return fixedPageCounter.countNextFixedPage(
queryFactory,
QLikes.likes,
pageable,
isLikedTemplateByMember(memberId)
);
}

private static BooleanExpression isLikedTemplateByMember(Long memberId) {
BooleanExpression isLikedByMemberId = QLikes.likes.member.id.eq(memberId);
BooleanExpression isLikedTemplateByMemberId = QLikes.likes.template.member.id.eq(memberId);
BooleanExpression isTemplatePublic = QLikes.likes.template.visibility.eq(Visibility.PUBLIC);

return isLikedByMemberId.and(isLikedTemplateByMemberId.or(isTemplatePublic));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import codezap.global.exception.CodeZapException;
import codezap.global.exception.ErrorCode;
import codezap.global.pagination.FixedPage;
import codezap.template.domain.Template;
import codezap.template.domain.Visibility;
import lombok.RequiredArgsConstructor;
Expand All @@ -28,12 +28,16 @@ public List<Template> findByMemberId(Long id) {
return templateJpaRepository.findByMemberId(id);
}

public Page<Template> findAll(
public FixedPage<Template> findAll(
Long memberId, String keyword, Long categoryId, List<Long> tagIds, Visibility visibility, Pageable pageable
) {
return templateQueryDSLRepository.findTemplates(memberId, keyword, categoryId, tagIds, visibility, pageable);
}

public FixedPage<Template> findAllLikedByMemberId(Long memberId, Pageable pageable) {
return templateQueryDSLRepository.findAllLikedByMemberId(memberId, pageable);
}

public boolean existsByCategoryId(Long categoryId) {
return templateJpaRepository.existsByCategoryId(categoryId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import java.util.HashSet;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import codezap.category.domain.Category;
import codezap.global.exception.CodeZapException;
import codezap.global.exception.ErrorCode;
import codezap.global.pagination.FixedPage;
import codezap.member.domain.Member;
import codezap.template.domain.Template;
import codezap.template.domain.Visibility;
Expand Down Expand Up @@ -45,7 +45,7 @@ public List<Template> getByMemberId(Long memberId) {
return templateRepository.findByMemberId(memberId);
}

public Page<Template> findAllBy(
public FixedPage<Template> findAllBy(
Long memberId,
String keyword,
Long categoryId,
Expand All @@ -56,6 +56,10 @@ public Page<Template> findAllBy(
return templateRepository.findAll(memberId, keyword, categoryId, tagIds, visibility, pageable);
}

public FixedPage<Template> findAllByMemberId(Long memberId, Pageable pageable) {
return templateRepository.findAllLikedByMemberId(memberId, pageable);
}

@Transactional
public Template update(
Member member,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import jakarta.annotation.Nullable;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -13,10 +12,10 @@
import codezap.category.service.CategoryService;
import codezap.global.exception.CodeZapException;
import codezap.global.exception.ErrorCode;
import codezap.global.pagination.FixedPage;
import codezap.likes.service.LikedChecker;
import codezap.likes.service.LikesService;
import codezap.member.domain.Member;
import codezap.member.service.MemberService;
import codezap.tag.domain.Tag;
import codezap.tag.service.TagService;
import codezap.template.domain.SourceCode;
Expand Down Expand Up @@ -45,7 +44,6 @@ public class TemplateApplicationService {
private final TagService tagService;
private final ThumbnailService thumbnailService;
private final LikesService likesService;
private final MemberService memberService;

@Transactional
public Long create(Member member, CreateTemplateRequest createTemplateRequest) {
Expand Down Expand Up @@ -94,7 +92,7 @@ public FindAllTemplatesResponse findAllBy(
List<Long> tagIds,
Pageable pageable
) {
Page<Template> templates = templateService.findAllBy(
FixedPage<Template> templates = templateService.findAllBy(
memberId, keyword, categoryId, tagIds, Visibility.PUBLIC, pageable
);
return makeAllTemplatesResponse(templates, (template) -> false);
Expand All @@ -108,7 +106,7 @@ public FindAllTemplatesResponse findAllBy(
Pageable pageable,
Member loginMember
) {
Page<Template> templates = templateService.findAllBy(
FixedPage<Template> templates = templateService.findAllBy(
memberId, keyword, categoryId, tagIds, getVisibilityLevel(memberId, loginMember), pageable
);
return makeAllTemplatesResponse(templates, (template -> likesService.isLiked(loginMember, template)));
Expand All @@ -123,18 +121,17 @@ private Visibility getVisibilityLevel(Long memberId, Member loginMember) {
}

public FindAllTemplatesResponse findAllByLiked(Long memberId, Pageable pageable) {
Page<Template> likeTemplate = likesService.findAllByMemberId(memberId, pageable);
FixedPage<Template> likeTemplate = templateService.findAllByMemberId(memberId, pageable);
return makeAllTemplatesResponse(likeTemplate, (template -> true));
}

private FindAllTemplatesResponse makeAllTemplatesResponse(Page<Template> page, LikedChecker likedChecker) {
List<Template> templates = page.getContent();
private FindAllTemplatesResponse makeAllTemplatesResponse(FixedPage<Template> page, LikedChecker likedChecker) {
List<Template> templates = page.contents();
List<FindAllTemplateItemResponse> findAllTemplateByResponse =
getFindAllTemplateItemResponses(templates, likedChecker);

return new FindAllTemplatesResponse(
page.getTotalPages(),
page.getTotalElements(),
page.nextPages(),
findAllTemplateByResponse);
}

Expand Down
Loading