Skip to content

Commit

Permalink
refactor: 글 조회시 전체 개수가 같이 반환되도록 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
cookienc committed Feb 14, 2024
1 parent 6dec2bc commit 75a4342
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,34 @@ public static <T extends IdExtractable> PageResponse<T> of(final List<T> respons
return new PageResponse<>(limitResponses, PageInfo.normal(getLastElementId(limitResponses)));
}

public record PageInfo(boolean isLast, Long nextCursor) {
public static <T extends IdExtractable> PageResponse<T> of(final List<T> responses,
final PageParams pageParams,
final long total
) {
final int limit = pageParams.limit();
if (isLastPage(responses, limit)) {
return new PageResponse<>(responses, PageInfo.last(total));
}
final List<T> limitResponses = responses.subList(0, pageParams.getLimitForQuery());
return new PageResponse<>(limitResponses, PageInfo.normal(getLastElementId(limitResponses), total));
}

public record PageInfo(boolean isLast, Long nextCursor, Long totalCount) {

public static PageInfo last() {
return new PageInfo(true, null);
return new PageInfo(true, null, null);
}

public static PageInfo last(final Long totalCount) {
return new PageInfo(true, null, totalCount);
}

public static PageInfo normal(final Long nextCursor) {
return new PageInfo(false, nextCursor);
return new PageInfo(false, nextCursor, null);
}

public static PageInfo normal(final Long nextCursor, final Long totalCount) {
return new PageInfo(false, nextCursor, totalCount);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package touch.baton.domain.common.vo;

import java.util.List;

public record Page<T>(List<T> contents, long total) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import touch.baton.domain.common.vo.Page;
import touch.baton.domain.runnerpost.command.RunnerPost;
import touch.baton.domain.runnerpost.command.vo.ReviewStatus;
import touch.baton.domain.tag.command.RunnerPostTag;
Expand All @@ -26,7 +27,7 @@ public class RunnerPostPageRepository {

private final JPAQueryFactory jpaQueryFactory;

public List<RunnerPost> pageByReviewStatusAndTagReducedName(final Long previousLastId,
public Page<RunnerPost> pageByReviewStatusAndTagReducedName(final Long previousLastId,
final int limit,
final TagReducedName tagReducedName,
final ReviewStatus reviewStatus
Expand All @@ -44,7 +45,16 @@ public List<RunnerPost> pageByReviewStatusAndTagReducedName(final Long previousL
.where(tag.tagReducedName.eq(tagReducedName));
}

return query.fetch();
final JPAQuery<RunnerPost> countQuery = jpaQueryFactory.selectFrom(runnerPost);

if (tagReducedName != null) {
countQuery.leftJoin(runnerPost.runnerPostTags.runnerPostTags, runnerPostTag)
.leftJoin(runnerPostTag.tag, tag)
.where(tag.tagReducedName.eq(tagReducedName));
}

final long count = countQuery.stream().count();
return new Page<>(query.fetch(), count);
}

public List<RunnerPost> pageBySupporterIdAndReviewStatus(final Long previousLastId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.transaction.annotation.Transactional;
import touch.baton.domain.common.request.PageParams;
import touch.baton.domain.common.response.PageResponse;
import touch.baton.domain.common.vo.Page;
import touch.baton.domain.member.command.Runner;
import touch.baton.domain.member.command.SupporterRunnerPost;
import touch.baton.domain.member.query.repository.SupporterRunnerPostQueryRepository;
Expand Down Expand Up @@ -42,13 +43,13 @@ public PageResponse<RunnerPostResponse.Simple> pageRunnerPostByTagNameAndReviewS
final PageParams pageParams,
final ReviewStatus reviewStatus
) {
final List<RunnerPost> runnerPosts = runnerPostPageRepository.pageByReviewStatusAndTagReducedName(pageParams.cursor(), pageParams.getLimitForQuery(), TagReducedName.nullableInstance(tagName), reviewStatus);
final List<RunnerPostTag> runnerPostTags = runnerPostPageRepository.findRunnerPostTagsByRunnerPosts(runnerPosts);
final RunnerPostsApplicantCount runnerPostsApplicantCount = readRunnerPostsApplicantCount(runnerPosts);
final List<RunnerPostResponse.Simple> responses = runnerPosts.stream()
final Page<RunnerPost> runnerPosts = runnerPostPageRepository.pageByReviewStatusAndTagReducedName(pageParams.cursor(), pageParams.getLimitForQuery(), TagReducedName.nullableInstance(tagName), reviewStatus);
final List<RunnerPostTag> runnerPostTags = runnerPostPageRepository.findRunnerPostTagsByRunnerPosts(runnerPosts.contents());
final RunnerPostsApplicantCount runnerPostsApplicantCount = readRunnerPostsApplicantCount(runnerPosts.contents());
final List<RunnerPostResponse.Simple> responses = runnerPosts.contents().stream()
.map(runnerPost -> RunnerPostResponse.Simple.of(runnerPost, runnerPostsApplicantCount.getApplicantCountById(runnerPost.getId()), runnerPostTags))
.toList();
return PageResponse.of(responses, pageParams);
return PageResponse.of(responses, pageParams, runnerPosts.total());
}

public PageResponse<RunnerPostResponse.Simple> pageRunnerPostBySupporterIdAndReviewStatus(final PageParams pageParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
final String 액세스_토큰 = oauthLoginTestManager.소셜_회원입을_진행한__액세스_토큰을_반환한다(FakeAuthCodes.hyenaAuthCode());

final Long 러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final long 전체_게시글_수 = 1;

final RunnerPost 러너_게시글 = runnerPostRepository.getByRunnerPostId(러너_게시글_식별자값);
final long 서포터_지원자_수 = runnerPostRepository.countApplicantByRunnerPostId(러너_게시글_식별자값);
Expand All @@ -39,7 +40,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
ReviewStatus.NOT_STARTED,
List.of("자바", "스프링")
);
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last();
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last(전체_게시글_);
final PageResponse<RunnerPostResponse.Simple> 기대된_러너_게시글_전체_Simple_페이징_응답 = 러너_게시글_전체_Simple_페이징_응답(
List.of(기대된_러너_게시글_Simple_응답),
기대된_페이징_정보
Expand All @@ -63,6 +64,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {

final Long 다음_페이지_러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final Long 이전_페이지_러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final long 전체_게시글_수 = 2;

final RunnerPost 다음_페이지_러너_게시글 = runnerPostRepository.getByRunnerPostId(다음_페이지_러너_게시글_식별자값);
final long 다음_페이지_게시글_서포터_지원자_수 = runnerPostRepository.countApplicantByRunnerPostId(다음_페이지_러너_게시글_식별자값);
Expand All @@ -76,7 +78,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
ReviewStatus.NOT_STARTED,
List.of("자바", "스프링")
);
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last();
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last(전체_게시글_);
final PageResponse<RunnerPostResponse.Simple> 기대된_러너_게시글_전체_Simple_페이징_응답 = 러너_게시글_전체_Simple_페이징_응답(
List.of(기대된_러너_게시글_Simple_응답),
기대된_페이징_정보
Expand All @@ -99,6 +101,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
final String 액세스_토큰 = oauthLoginTestManager.소셜_회원입을_진행한__액세스_토큰을_반환한다(FakeAuthCodes.hyenaAuthCode());

final Long 러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final long 전체_게시글_수 = 1;

final RunnerPost 러너_게시글 = runnerPostRepository.getByRunnerPostId(러너_게시글_식별자값);
final long 서포터_지원자_수 = runnerPostRepository.countApplicantByRunnerPostId(러너_게시글_식별자값);
Expand All @@ -112,7 +115,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
ReviewStatus.NOT_STARTED,
List.of("자바", "스프링")
);
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last();
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last(전체_게시글_);
final PageResponse<RunnerPostResponse.Simple> 기대된_러너_게시글_전체_Simple_페이징_응답 = 러너_게시글_전체_Simple_페이징_응답(
List.of(기대된_러너_게시글_Simple_응답),
기대된_페이징_정보
Expand All @@ -136,6 +139,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {

final Long 다음_페이지_러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final Long 이전_페이지_러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final long 전체_게시글_수 = 2;

final RunnerPost 다음_페이지_러너_게시글 = runnerPostRepository.getByRunnerPostId(다음_페이지_러너_게시글_식별자값);
final long 다음_페이지_게시글_서포터_지원자_수 = runnerPostRepository.countApplicantByRunnerPostId(다음_페이지_러너_게시글_식별자값);
Expand All @@ -149,7 +153,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
ReviewStatus.NOT_STARTED,
List.of("자바", "스프링")
);
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last();
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last(전체_게시글_);
final PageResponse<RunnerPostResponse.Simple> 기대된_러너_게시글_전체_Simple_페이징_응답 = 러너_게시글_전체_Simple_페이징_응답(
List.of(기대된_러너_게시글_Simple_응답),
기대된_페이징_정보
Expand All @@ -172,6 +176,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
final String 액세스_토큰 = oauthLoginTestManager.소셜_회원입을_진행한__액세스_토큰을_반환한다(FakeAuthCodes.hyenaAuthCode());

final Long 러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final long 전체_게시글_수 = 1;

final RunnerPost 러너_게시글 = runnerPostRepository.getByRunnerPostId(러너_게시글_식별자값);
final long 서포터_지원자_수 = runnerPostRepository.countApplicantByRunnerPostId(러너_게시글_식별자값);
Expand All @@ -185,7 +190,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
ReviewStatus.NOT_STARTED,
List.of("자바", "스프링")
);
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last();
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last(전체_게시글_);
final PageResponse<RunnerPostResponse.Simple> 기대된_러너_게시글_전체_Simple_페이징_응답 = 러너_게시글_전체_Simple_페이징_응답(
List.of(기대된_러너_게시글_Simple_응답),
기대된_페이징_정보
Expand All @@ -209,6 +214,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {

final Long 다음_페이지_러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final Long 이전_페이지_러너_게시글_식별자값 = 러너_게시글_생성을_성공하고_러너_게시글_식별자값을_반환한다(액세스_토큰);
final long 전체_게시글_수 = 2;

final RunnerPost 현재_페이지_러너_게시글 = runnerPostRepository.getByRunnerPostId(다음_페이지_러너_게시글_식별자값);
final long 현재_페이지_게시글_서포터_지원자_수 = runnerPostRepository.countApplicantByRunnerPostId(다음_페이지_러너_게시글_식별자값);
Expand All @@ -222,7 +228,7 @@ class RunnerPostPageAssuredTest extends AssuredTestConfig {
ReviewStatus.NOT_STARTED,
List.of("자바", "스프링")
);
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last();
final PageResponse.PageInfo 기대된_페이징_정보 = PageResponse.PageInfo.last(전체_게시글_);
final PageResponse<RunnerPostResponse.Simple> 기대된_러너_게시글_전체_Simple_페이징_응답 = 러너_게시글_전체_Simple_페이징_응답(
List.of(기대된_러너_게시글_Simple_응답),
기대된_페이징_정보
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ void readRunnerPostBySupporterIdAndReviewStatus() throws Exception {
fieldWithPath("data.[].runnerProfile.imageUrl").type(STRING).description("러너 게시글의 러너 프로필 이미지"),
fieldWithPath("data.[].tags.[]").type(ARRAY).description("러너 게시글의 태그 목록"),
fieldWithPath("pageInfo.isLast").type(BOOLEAN).description("마지막 페이지 여부"),
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서")
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서"),
fieldWithPath("pageInfo.totalCount").type(NUMBER).optional().description("전체 페이지 수").ignored()
))
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void readRunnerPostsByTagNamesAndReviewStatus() throws Exception {
0L,
List.of(RunnerPostTagFixture.create(spyRunnerPost, javaTag), RunnerPostTagFixture.create(spyRunnerPost, springTag))
));
final PageResponse<RunnerPostResponse.Simple> pageResponse = PageResponse.of(responses, new PageParams(2L, 10));
final PageResponse<RunnerPostResponse.Simple> pageResponse = PageResponse.of(responses, new PageParams(2L, 10), 1);
when(runnerPostQueryService.pageRunnerPostByTagNameAndReviewStatus(anyString(), any(PageParams.class), any(ReviewStatus.class)))
.thenReturn(pageResponse);

Expand Down Expand Up @@ -92,7 +92,8 @@ void readRunnerPostsByTagNamesAndReviewStatus() throws Exception {
fieldWithPath("data.[].runnerProfile.imageUrl").type(STRING).description("러너 게시글의 러너 프로필 이미지"),
fieldWithPath("data.[].tags.[]").type(ARRAY).description("러너 게시글의 태그 목록"),
fieldWithPath("pageInfo.isLast").type(BOOLEAN).description("마지막 페이지 여부"),
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서")
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서"),
fieldWithPath("pageInfo.totalCount").type(NUMBER).description("전체 페이지 수")
))
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ void readRunnerPostByLoginedRunnerAndReviewStatus() throws Exception {
.description("서포터 id (서포터가 존재할 때 NUMBER, 아닌 경우에 NULL)"),
fieldWithPath("data.[].tags.[]").type(ARRAY).description("러너 게시글의 태그 목록"),
fieldWithPath("pageInfo.isLast").type(BOOLEAN).description("마지막 페이지 여부"),
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서")
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서"),
fieldWithPath("pageInfo.totalCount").type(NUMBER).optional().description("전체 페이지 수").ignored()
))
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ void readRunnerPostByLoginedSupporterAndReviewStatus() throws Exception {
fieldWithPath("data.[].runnerProfile.imageUrl").type(STRING).description("러너 게시글의 러너 프로필 이미지"),
fieldWithPath("data.[].tags.[]").type(ARRAY).description("러너 게시글의 태그 목록"),
fieldWithPath("pageInfo.isLast").type(BOOLEAN).description("마지막 페이지 여부"),
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서")
fieldWithPath("pageInfo.nextCursor").type(NUMBER).optional().description("다음 커서"),
fieldWithPath("pageInfo.totalCount").type(NUMBER).optional().description("전체 페이지 수").ignored()
))
);
}
Expand Down
Loading

0 comments on commit 75a4342

Please sign in to comment.