Skip to content

Commit

Permalink
[Refactor] 내 일정 카테고리별 개수 조회 4방 쿼리를 서브쿼리를 통해서 1번의 Network I/O로 변경한다 (#176
Browse files Browse the repository at this point in the history
)

* feat: 내 일정 카테고리별 커피챗 개수 조회 Projection Dto 정의

* feat: 내 일정 카테고리별 커피챗 개수 조회 SubQuery Fetching 쿼리

* refactor: GetCoffeeChatScheduleUseCase's getEachCategoryCounts 서브쿼리 적용

* refactor: 내 일정 카테고리별 개수 서브쿼리 메소드 추출
  • Loading branch information
sjiwon authored Feb 26, 2024
1 parent fc4ff80 commit 03450a1
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.koddy.server.coffeechat.application.usecase.query.GetMenteeCoffeeChats;
import com.koddy.server.coffeechat.application.usecase.query.GetMentorCoffeeChats;
import com.koddy.server.coffeechat.application.usecase.query.response.CoffeeChatEachCategoryCounts;
import com.koddy.server.coffeechat.domain.repository.CoffeeChatRepository;
import com.koddy.server.coffeechat.domain.repository.query.CoffeeChatScheduleQueryRepository;
import com.koddy.server.coffeechat.domain.repository.query.response.MenteeCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.response.MentorCoffeeChatScheduleData;
Expand All @@ -20,40 +19,17 @@

@UseCase
public class GetCoffeeChatScheduleUseCase {
private final CoffeeChatRepository coffeeChatRepository;
private final CoffeeChatScheduleQueryRepository coffeeChatScheduleQueryRepository;

public GetCoffeeChatScheduleUseCase(
final CoffeeChatRepository coffeeChatRepository,
final CoffeeChatScheduleQueryRepository coffeeChatScheduleQueryRepository
) {
this.coffeeChatRepository = coffeeChatRepository;
public GetCoffeeChatScheduleUseCase(final CoffeeChatScheduleQueryRepository coffeeChatScheduleQueryRepository) {
this.coffeeChatScheduleQueryRepository = coffeeChatScheduleQueryRepository;
}

public CoffeeChatEachCategoryCounts getEachCategoryCounts(final Authenticated authenticated) {
if (authenticated.isMentor()) {
return getMentorCoffeeChatCounts(authenticated.id);
return CoffeeChatEachCategoryCounts.from(coffeeChatScheduleQueryRepository.fetchMentorCoffeeChatCountPerCategory(authenticated.id));
}
return getMenteeCoffeeChatCounts(authenticated.id);
}

private CoffeeChatEachCategoryCounts getMentorCoffeeChatCounts(final long mentorId) {
return new CoffeeChatEachCategoryCounts(
coffeeChatRepository.getMentorWaitingCoffeeChatCount(mentorId),
coffeeChatRepository.getMentorSuggestedCoffeeChatCount(mentorId),
coffeeChatRepository.getMentorScheduledCoffeeChatCount(mentorId),
coffeeChatRepository.getMentorPassedCoffeeChatCount(mentorId)
);
}

private CoffeeChatEachCategoryCounts getMenteeCoffeeChatCounts(final long menteeId) {
return new CoffeeChatEachCategoryCounts(
coffeeChatRepository.getMenteeWaitingCoffeeChatCount(menteeId),
coffeeChatRepository.getMenteeSuggestedCoffeeChatCount(menteeId),
coffeeChatRepository.getMenteeScheduledCoffeeChatCount(menteeId),
coffeeChatRepository.getMenteePassedCoffeeChatCount(menteeId)
);
return CoffeeChatEachCategoryCounts.from(coffeeChatScheduleQueryRepository.fetchMenteeCoffeeChatCountPerCategory(authenticated.id));
}

public SliceResponse<List<MentorCoffeeChatScheduleData>> getMentorSchedules(final GetMentorCoffeeChats query) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package com.koddy.server.coffeechat.application.usecase.query.response;

import com.koddy.server.coffeechat.domain.repository.query.response.CoffeeChatCountPerCategory;

public record CoffeeChatEachCategoryCounts(
long waiting,
long suggested,
long scheduled,
long passed
) {
public static CoffeeChatEachCategoryCounts from(final CoffeeChatCountPerCategory query) {
return new CoffeeChatEachCategoryCounts(
query.waiting(),
query.suggested(),
query.scheduled(),
query.passed()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.koddy.server.coffeechat.domain.repository.query;

import com.koddy.server.coffeechat.domain.repository.query.response.CoffeeChatCountPerCategory;
import com.koddy.server.coffeechat.domain.repository.query.response.MenteeCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.response.MentorCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.spec.MenteeCoffeeChatQueryCondition;
Expand All @@ -8,6 +9,16 @@
import org.springframework.data.domain.Slice;

public interface CoffeeChatScheduleQueryRepository {
/**
* 멘토 카테고리별 커피챗 개수
*/
CoffeeChatCountPerCategory fetchMentorCoffeeChatCountPerCategory(final long mentorId);

/**
* 멘티 카테고리별 커피챗 개수
*/
CoffeeChatCountPerCategory fetchMenteeCoffeeChatCountPerCategory(final long menteeId);

/**
* 멘토 내 일정
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.koddy.server.coffeechat.domain.repository.query;

import com.koddy.server.coffeechat.domain.model.CoffeeChatStatus;
import com.koddy.server.coffeechat.domain.repository.query.response.CoffeeChatCountPerCategory;
import com.koddy.server.coffeechat.domain.repository.query.response.MenteeCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.response.MentorCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.response.QCoffeeChatCountPerCategory;
import com.koddy.server.coffeechat.domain.repository.query.response.QMenteeCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.response.QMentorCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.spec.MenteeCoffeeChatQueryCondition;
import com.koddy.server.coffeechat.domain.repository.query.spec.MentorCoffeeChatQueryCondition;
import com.koddy.server.global.annotation.KoddyReadOnlyTransactional;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.data.domain.Pageable;
Expand All @@ -21,6 +25,7 @@
import static com.koddy.server.coffeechat.domain.model.QCoffeeChat.coffeeChat;
import static com.koddy.server.member.domain.model.mentee.QMentee.mentee;
import static com.koddy.server.member.domain.model.mentor.QMentor.mentor;
import static com.querydsl.jpa.JPAExpressions.select;

@Repository
@KoddyReadOnlyTransactional
Expand All @@ -31,6 +36,45 @@ public CoffeeChatScheduleQueryRepositoryImpl(final JPAQueryFactory query) {
this.query = query;
}

@Override
public CoffeeChatCountPerCategory fetchMentorCoffeeChatCountPerCategory(final long mentorId) {
return query
.selectDistinct(fetchCoffeeChatCountPerCategory())
.from(coffeeChat)
.where(coffeeChat.mentorId.eq(mentorId))
.fetchOne();
}

@Override
public CoffeeChatCountPerCategory fetchMenteeCoffeeChatCountPerCategory(final long menteeId) {
return query
.selectDistinct(fetchCoffeeChatCountPerCategory())
.from(coffeeChat)
.where(coffeeChat.menteeId.eq(menteeId))
.fetchOne();
}

private QCoffeeChatCountPerCategory fetchCoffeeChatCountPerCategory() {
return new QCoffeeChatCountPerCategory(
fetchCountWithStatus(CoffeeChatStatus.withWaitingCategory(), "waiting"),
fetchCountWithStatus(CoffeeChatStatus.withSuggstedCategory(), "suggested"),
fetchCountWithStatus(CoffeeChatStatus.withScheduledCategory(), "scheduled"),
fetchCountWithStatus(CoffeeChatStatus.withPassedCategory(), "passed")
);
}

private Expression<Long> fetchCountWithStatus(
final List<CoffeeChatStatus> status,
final String alias
) {
return ExpressionUtils.as(
select(coffeeChat.count())
.from(coffeeChat)
.where(coffeeChat.status.in(status)),
alias
);
}

@Override
public Slice<MentorCoffeeChatScheduleData> fetchMentorCoffeeChatSchedules(
final MentorCoffeeChatQueryCondition condition,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.koddy.server.coffeechat.domain.repository.query.response;

import com.querydsl.core.annotations.QueryProjection;

public record CoffeeChatCountPerCategory(
long waiting,
long suggested,
long scheduled,
long passed
) {
@QueryProjection
public CoffeeChatCountPerCategory {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.koddy.server.coffeechat.domain.model.CoffeeChat;
import com.koddy.server.coffeechat.domain.model.CoffeeChatStatus;
import com.koddy.server.coffeechat.domain.repository.CoffeeChatRepository;
import com.koddy.server.coffeechat.domain.repository.query.response.CoffeeChatCountPerCategory;
import com.koddy.server.coffeechat.domain.repository.query.response.MenteeCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.spec.MenteeCoffeeChatQueryCondition;
import com.koddy.server.common.fixture.CoffeeChatFixture.MenteeFlow;
Expand Down Expand Up @@ -86,7 +87,12 @@ void setUp() {
@Test
@DisplayName("0. 멘티의 상태별 커피챗 개수를 조회한다 [대기, 제안, 예정, 지나간]")
void counts() {
final CoffeeChatCountPerCategory result = sut.fetchMenteeCoffeeChatCountPerCategory(mentees[0].getId());
assertAll(
() -> assertThat(result.waiting()).isEqualTo(11),
() -> assertThat(result.suggested()).isEqualTo(7),
() -> assertThat(result.scheduled()).isEqualTo(3),
() -> assertThat(result.passed()).isEqualTo(9),
() -> assertThat(coffeeChatRepository.getMenteeWaitingCoffeeChatCount(mentees[0].getId())).isEqualTo(11),
() -> assertThat(coffeeChatRepository.getMenteeSuggestedCoffeeChatCount(mentees[0].getId())).isEqualTo(7),
() -> assertThat(coffeeChatRepository.getMenteeScheduledCoffeeChatCount(mentees[0].getId())).isEqualTo(3),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.koddy.server.coffeechat.domain.model.CoffeeChat;
import com.koddy.server.coffeechat.domain.model.CoffeeChatStatus;
import com.koddy.server.coffeechat.domain.repository.CoffeeChatRepository;
import com.koddy.server.coffeechat.domain.repository.query.response.CoffeeChatCountPerCategory;
import com.koddy.server.coffeechat.domain.repository.query.response.MentorCoffeeChatScheduleData;
import com.koddy.server.coffeechat.domain.repository.query.spec.MentorCoffeeChatQueryCondition;
import com.koddy.server.common.fixture.CoffeeChatFixture.MenteeFlow;
Expand Down Expand Up @@ -86,7 +87,12 @@ void setUp() {
@Test
@DisplayName("0. 멘토의 상태별 커피챗 개수를 조회한다 [대기, 제안, 예정, 지나간]")
void counts() {
final CoffeeChatCountPerCategory result = sut.fetchMentorCoffeeChatCountPerCategory(mentors[0].getId());
assertAll(
() -> assertThat(result.waiting()).isEqualTo(11),
() -> assertThat(result.suggested()).isEqualTo(7),
() -> assertThat(result.scheduled()).isEqualTo(3),
() -> assertThat(result.passed()).isEqualTo(9),
() -> assertThat(coffeeChatRepository.getMentorWaitingCoffeeChatCount(mentors[0].getId())).isEqualTo(11),
() -> assertThat(coffeeChatRepository.getMentorSuggestedCoffeeChatCount(mentors[0].getId())).isEqualTo(7),
() -> assertThat(coffeeChatRepository.getMentorScheduledCoffeeChatCount(mentors[0].getId())).isEqualTo(3),
Expand Down

0 comments on commit 03450a1

Please sign in to comment.