Skip to content

Commit

Permalink
feat-be: API 쿼리 최적화 (#707)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Kwoun Ki Ho <73146678+Chocochip101@users.noreply.github.com>
Co-authored-by: 최가희 <60508828+cutehumanS2@users.noreply.github.com>
Co-authored-by: Do Yeop Kim <113661364+Dobby-Kim@users.noreply.github.com>
  • Loading branch information
4 people committed Sep 25, 2024
1 parent 5de1fa6 commit 24312fa
Show file tree
Hide file tree
Showing 35 changed files with 502 additions and 165 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.cruru.applicant.domain.dto;

import com.cruru.applicant.controller.response.ApplicantCardResponse;
import java.time.LocalDateTime;

public record ApplicantCard(
long id,

String name,

LocalDateTime createdAt,

Boolean isRejected,

long evaluationCount,

double averageScore,

long processId
) {

public ApplicantCardResponse toResponse() {
return new ApplicantCardResponse(id, name, createdAt, isRejected, (int) evaluationCount, averageScore);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
package com.cruru.applicant.domain.repository;

import com.cruru.applicant.domain.Applicant;
import com.cruru.applicant.domain.dto.ApplicantCard;
import com.cruru.dashboard.domain.Dashboard;
import com.cruru.process.domain.Process;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface ApplicantRepository extends JpaRepository<Applicant, Long> {

List<Applicant> findAllByProcess(Process process);

long countByProcess(Process process);

Optional<Applicant> findByEmail(String email);
@Query("""
SELECT new com.cruru.applicant.domain.dto.ApplicantCard(
a.id, a.name, a.createdDate, a.isRejected, COUNT(e), COALESCE(AVG(e.score), 0.00), a.process.id
)
FROM Applicant a
LEFT JOIN Evaluation e ON e.applicant = a
WHERE a.process IN :processes
GROUP BY a.id, a.name, a.createdDate, a.isRejected, a.process.id
""")
List<ApplicantCard> findApplicantCardsByProcesses(@Param("processes") List<Process> processes);

@Query("""
SELECT new com.cruru.applicant.domain.dto.ApplicantCard(
a.id, a.name, a.createdDate, a.isRejected, COUNT(e), COALESCE(AVG(e.score), 0.00), a.process.id
)
FROM Applicant a
LEFT JOIN Evaluation e ON e.applicant = a
WHERE a.process = :process
GROUP BY a.id, a.name, a.createdDate, a.isRejected
""")
List<ApplicantCard> findApplicantCardsByProcess(@Param("process") Process process);

@Query("SELECT a FROM Applicant a JOIN FETCH a.process p JOIN FETCH p.dashboard d WHERE d = :dashboard")
List<Applicant> findAllByDashboard(@Param("dashboard") Dashboard dashboard);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

public interface EvaluationRepository extends JpaRepository<Evaluation, Long> {

int countByApplicantAndProcess(Applicant applicant, Process process);

List<Evaluation> findAllByProcessAndApplicant(Process process, Applicant applicant);

void deleteByProcess(Process process);
void deleteByProcessId(long processId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ private ApplicantBasicResponse toApplicantBasicResponse(Applicant applicant) {

public ApplicantAnswerResponses readDetailById(long applicantId) {
Applicant applicant = applicantService.findById(applicantId);
List<Answer> answers = answerService.findAllByApplicant(applicant);
List<Answer> answers = answerService.findAllByApplicantWithQuestions(applicant);
List<AnswerResponse> answerResponses = answerService.toAnswerResponses(answers);
return new ApplicantAnswerResponses(answerResponses);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import com.cruru.applicant.controller.request.ApplicantCreateRequest;
import com.cruru.applicant.controller.request.ApplicantMoveRequest;
import com.cruru.applicant.controller.request.ApplicantUpdateRequest;
import com.cruru.applicant.controller.response.ApplicantCardResponse;
import com.cruru.applicant.controller.response.ApplicantResponse;
import com.cruru.applicant.domain.Applicant;
import com.cruru.applicant.domain.dto.ApplicantCard;
import com.cruru.applicant.domain.repository.ApplicantRepository;
import com.cruru.applicant.exception.ApplicantNotFoundException;
import com.cruru.applicant.exception.badrequest.ApplicantRejectException;
Expand Down Expand Up @@ -95,18 +95,11 @@ public ApplicantResponse toApplicantResponse(Applicant applicant) {
);
}

public ApplicantCardResponse toApplicantCardResponse(
Applicant applicant,
int evaluationCount,
double averageScore
) {
return new ApplicantCardResponse(
applicant.getId(),
applicant.getName(),
applicant.getCreatedDate(),
applicant.isRejected(),
evaluationCount,
averageScore
);
public List<ApplicantCard> findApplicantCards(List<Process> processes) {
return applicantRepository.findApplicantCardsByProcesses(processes);
}

public List<ApplicantCard> findApplicantCards(Process process) {
return applicantRepository.findApplicantCardsByProcess(process);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,6 @@ public void create(EvaluationCreateRequest request, Process process, Applicant a
evaluationRepository.save(new Evaluation(request.score(), request.content(), process, applicant));
}

public int count(Process process, Applicant applicant) {
return evaluationRepository.countByApplicantAndProcess(applicant, process);
}

public double calculateAverageScore(Process process, Applicant applicant) {
List<Evaluation> evaluations = findAllByProcessAndApplicant(process, applicant);
return evaluations.stream()
.mapToDouble(Evaluation::getScore)
.average()
.orElse(0.0);
}

public List<Evaluation> findAllByProcessAndApplicant(Process process, Applicant applicant) {
return evaluationRepository.findAllByProcessAndApplicant(process, applicant);
}
Expand All @@ -64,7 +52,7 @@ private boolean changeExists(EvaluationUpdateRequest request, Evaluation evaluat
return !(evaluation.getContent().equals(request.content()) && evaluation.getScore().equals(request.score()));
}

public void deleteByProcess(Process process) {
evaluationRepository.deleteByProcess(process);
public void deleteByProcess(long processId) {
evaluationRepository.deleteByProcessId(processId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,30 @@

import com.cruru.applyform.domain.ApplyForm;
import com.cruru.dashboard.domain.Dashboard;
import com.cruru.dashboard.domain.DashboardApplyFormDto;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface ApplyFormRepository extends JpaRepository<ApplyForm, Long> {

Optional<ApplyForm> findByDashboard(Dashboard dashboardId);
Optional<ApplyForm> findByDashboard(Dashboard dashboard);

@Query("""
SELECT af FROM ApplyForm af
JOIN FETCH af.dashboard d
WHERE d.id = :dashboardId
""")
Optional<ApplyForm> findByDashboardId(long dashboardId);

@Query("""
SELECT new com.cruru.dashboard.domain.DashboardApplyFormDto(d, a)
FROM ApplyForm a
JOIN FETCH a.dashboard d
JOIN FETCH d.club c
WHERE c.id = :clubId
""")
List<DashboardApplyFormDto> findAllByClub(@Param("clubId") Long clubId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ public ApplyForm findById(Long applyFormId) {
.orElseThrow(ApplyFormNotFoundException::new);
}

public ApplyForm findByDashboardId(Long dashboardId) {
return applyFormRepository.findByDashboardId(dashboardId)
.orElseThrow(ApplyFormNotFoundException::new);
}

public ApplyForm findByDashboard(Dashboard dashboard) {
return applyFormRepository.findByDashboard(dashboard)
.orElseThrow(ApplyFormNotFoundException::new);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.cruru.dashboard.domain;

import com.cruru.applyform.domain.ApplyForm;

public record DashboardApplyFormDto(Dashboard dashboard, ApplyForm applyForm) {

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package com.cruru.dashboard.domain.repository;

import com.cruru.club.domain.Club;
import com.cruru.dashboard.domain.Dashboard;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface DashboardRepository extends JpaRepository<Dashboard, Long> {

List<Dashboard> findAllByClub(Club club);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.cruru.dashboard.facade;

import com.cruru.applicant.domain.Applicant;
import com.cruru.applicant.service.ApplicantService;
import com.cruru.applyform.controller.request.ApplyFormWriteRequest;
import com.cruru.applyform.domain.ApplyForm;
import com.cruru.applyform.service.ApplyFormService;
Expand All @@ -13,10 +12,8 @@
import com.cruru.dashboard.controller.response.DashboardsOfClubResponse;
import com.cruru.dashboard.controller.response.StatsResponse;
import com.cruru.dashboard.domain.Dashboard;
import com.cruru.dashboard.domain.DashboardApplyFormDto;
import com.cruru.dashboard.service.DashboardService;
import com.cruru.member.service.MemberService;
import com.cruru.process.domain.Process;
import com.cruru.process.service.ProcessService;
import com.cruru.question.controller.request.QuestionCreateRequest;
import com.cruru.question.service.QuestionService;
import java.time.Clock;
Expand All @@ -33,13 +30,10 @@
@RequiredArgsConstructor
public class DashboardFacade {

private final MemberService memberService;
private final ClubService clubService;
private final DashboardService dashboardService;
private final ApplyFormService applyFormService;
private final QuestionService questionService;
private final ProcessService processService;
private final ApplicantService applicantService;
private final Clock clock;

@Transactional
Expand All @@ -64,9 +58,7 @@ private ApplyFormWriteRequest toApplyFormWriteRequest(DashboardCreateRequest req
}

public DashboardsOfClubResponse findAllDashboardsByClubId(long clubId) {
Club club = clubService.findById(clubId);

List<Dashboard> dashboards = dashboardService.findAllByClub(club);
List<DashboardApplyFormDto> dashboards = dashboardService.findAllByClub(clubId);

String clubName = clubService.findById(clubId).getName();
LocalDateTime now = LocalDateTime.now(clock);
Expand All @@ -79,10 +71,12 @@ public DashboardsOfClubResponse findAllDashboardsByClubId(long clubId) {
return new DashboardsOfClubResponse(clubName, sortedDashboardPreviews);
}

private DashboardPreviewResponse createDashboardPreviewResponse(Dashboard dashboard) {
ApplyForm applyForm = applyFormService.findByDashboard(dashboard);
List<Applicant> allApplicants = getAllApplicantsByDashboardId(dashboard);
StatsResponse stats = calculateStats(allApplicants);
private DashboardPreviewResponse createDashboardPreviewResponse(DashboardApplyFormDto dashboardApplyformDto) {
Dashboard dashboard = dashboardApplyformDto.dashboard();
ApplyForm applyForm = dashboardApplyformDto.applyForm();

List<Applicant> applicants = dashboardService.findAllApplicants(dashboard);
StatsResponse stats = calculateStats(applicants);
return new DashboardPreviewResponse(
dashboard.getId(),
applyForm.getId(),
Expand Down Expand Up @@ -115,14 +109,6 @@ private List<DashboardPreviewResponse> sortDashboardPreviews(
return sortedDashboards;
}

private List<Applicant> getAllApplicantsByDashboardId(Dashboard dashboard) {
List<Process> processes = processService.findAllByDashboard(dashboard);
return processes.stream()
.flatMap(process -> applicantService.findAllByProcess(process)
.stream())
.toList();
}

private StatsResponse calculateStats(List<Applicant> allApplicants) {
int totalApplicants = allApplicants.size();
int totalFails = (int) allApplicants.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.cruru.dashboard.service;

import com.cruru.applicant.domain.Applicant;
import com.cruru.applicant.domain.repository.ApplicantRepository;
import com.cruru.applyform.domain.repository.ApplyFormRepository;
import com.cruru.club.domain.Club;
import com.cruru.dashboard.domain.Dashboard;
import com.cruru.dashboard.domain.DashboardApplyFormDto;
import com.cruru.dashboard.domain.repository.DashboardRepository;
import com.cruru.dashboard.exception.DashboardNotFoundException;
import com.cruru.process.domain.Process;
Expand All @@ -19,6 +23,8 @@ public class DashboardService {

private final DashboardRepository dashboardRepository;
private final ProcessRepository processRepository;
private final ApplicantRepository applicantRepository;
private final ApplyFormRepository applyFormRepository;

@Transactional
public Dashboard create(Club club) {
Expand All @@ -35,7 +41,11 @@ public Dashboard findById(Long id) {
.orElseThrow(DashboardNotFoundException::new);
}

public List<Dashboard> findAllByClub(Club club) {
return dashboardRepository.findAllByClub(club);
public List<DashboardApplyFormDto> findAllByClub(long clubId) {
return applyFormRepository.findAllByClub(clubId);
}

public List<Applicant> findAllApplicants(Dashboard dashboard) {
return applicantRepository.findAllByDashboard(dashboard);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.cruru.email.controller;

import com.cruru.email.facade.EmailFacade;
import com.cruru.email.controller.dto.EmailRequest;
import com.cruru.email.facade.EmailFacade;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand Down
2 changes: 1 addition & 1 deletion backend/src/main/java/com/cruru/email/domain/Email.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.cruru.BaseEntity;
import com.cruru.applicant.domain.Applicant;
import com.cruru.club.domain.Club;
import com.cruru.email.exception.EmailSubjectLengthException;
import com.cruru.email.exception.EmailContentLengthException;
import com.cruru.email.exception.EmailSubjectLengthException;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
Expand Down
Loading

0 comments on commit 24312fa

Please sign in to comment.