kookmin-sw / capstone-2024-31

[루틴업] 커뮤니티 기반 습관 형성 챌린지 앱
https://kookmin-sw.github.io/capstone-2024-31/
0 stars 3 forks source link

[backend/feature] 챌린지 필터링 및 페이징 검색 기능 구현 #87

Closed sukjuhong closed 6 months ago

sukjuhong commented 6 months ago

개요 :mag:

챌린지 모아보기 기능을 위한 챌린지 검색 기능을 구현했습니다.

연관된 이슈

80

작업사항 :memo:

querydsl을 사용한 동적 쿼리를 적용했습니다.

@Override
public List<Challenge> findByChallengeWithFilterAndPaging(Long cursorId, ChallengeFilter filter) {
  QChallenge challenge = QChallenge.challenge;
  BooleanExpression predicate = challenge.isNotNull();

  if (cursorId != 0) {
    predicate = challenge.id.lt(cursorId);
  }

  if (StringUtils.hasText(filter.name())) {
    predicate = challenge.challengeName.startsWith(filter.name());
  }

  predicate = predicate.and(challenge.isPrivate.eq(filter.isPrivate()));

  if (filter.category() != null) {
    predicate = predicate.and(challenge.category.eq(filter.category()));
  }

  return queryFactory
    .selectFrom(challenge)
    .where(predicate)
    .limit(DEFAULT_PAGE_SIZE)
    .fetch();
}

먼저 lt는 cursorId(맨 마지막으로 조회된 challengeId)보다 작은 id의 challenge만 조회하게 되어서, 현재 limit으로 10개가 조회가 되는데, 밑으로 스크롤해서 끝에 닿게되면 제일 아래에있는 challenge 기준으로 추가 조회를 일으키면 됩니다.

다음 챌린지 이름을 검색하게 된다면 해당 챌린지 이름으로 시작하는 챌린지만 검색하도록했고,

그 다음 비공개 여부 판단

그 다음 카테고리 선택 여부 판단입니다.

실제로 쿼리는

Hibernate: 
    select
        c1_0.id,
        c1_0.category,
        c1_0.certification_end_time,
        c1_0.certification_explanation,
        c1_0.certification_frequency,
        c1_0.certification_start_time,
        c1_0.certification_type,
        c1_0.challenge_explanation,
        c1_0.challenge_name,
        c1_0.challenge_period,
        c1_0.end_date,
        c1_0.failed_verification_image,
        c1_0.is_ended,
        c1_0.is_gallery_possible,
        c1_0.is_private,
        c1_0.maximum_people,
        c1_0.private_code,
        c1_0.start_date,
        c1_0.successful_verification_image,
        c1_0.total_participants 
    from
        challenges c1_0 
    where
        c1_0.id is not null 
        and c1_0.is_private=? 
        and c1_0.category=? 
    limit
        ?

이런 식으로 날아가게 되고, 이는 filter의 값에 따라 동적으로 변화합니다.

테스트 방법

ChallengeControllerTest에 get_challenge_with_filtering_and_paging라는 테스트 함수로 결과를 확인하시면 됩니다.

추가적으로 저는 fixture 사용이 잘 되는데, 이를 참고해서 테스트 코드 한번 진행해보시면 좋겠습니다.

ehyeok9 commented 6 months ago

LG !