From 86d61d4d8c9ea2a7e6e097272191f376f0189236 Mon Sep 17 00:00:00 2001 From: HongGit Date: Wed, 12 Mar 2025 17:35:48 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[refactor/#91]=20=EB=AC=B8=ED=95=AD?= =?UTF-8?q?=EC=84=B8=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20api=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProblemSetGetRepositoryCustom.java | 76 +++++++++++++++++++ .../service/ProblemSetGetService.java | 36 +-------- 2 files changed, 79 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java diff --git a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java new file mode 100644 index 0000000..d25052b --- /dev/null +++ b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java @@ -0,0 +1,76 @@ +package com.moplus.moplus_server.domain.problemset.repository; + +import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse; +import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse; +import com.moplus.moplus_server.admin.publish.domain.QPublish; +import com.moplus.moplus_server.domain.concept.domain.QConceptTag; +import com.moplus.moplus_server.domain.problem.domain.problem.QProblem; +import com.moplus.moplus_server.domain.problemset.domain.ProblemSet; +import com.querydsl.core.Tuple; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.time.LocalDate; +import java.util.*; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ProblemSetGetRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { + // 발행 날짜 조회 쿼리 + List publishedDates = queryFactory + .select(QPublish.publish.publishedDate) + .from(QPublish.publish) + .where(QPublish.publish.problemSetId.eq(problemSet.getId())) + .fetch(); + + // 문제 조회 쿼리 (문제 자체 정보만 조회) + List problemData = queryFactory + .select( + QProblem.problem.id, + QProblem.problem.problemCustomId, + QProblem.problem.title, + QProblem.problem.memo, + QProblem.problem.mainProblemImageUrl + ) + .from(QProblem.problem) + .where(QProblem.problem.id.in(problemSet.getProblemIds())) + .distinct() + .fetch(); + + // 태그 조회 쿼리 (각 문제별 태그만 조회) + Map> conceptTagMap = queryFactory + .select(QProblem.problem.id, QConceptTag.conceptTag.name) + .from(QProblem.problem) + .leftJoin(QConceptTag.conceptTag) + .on(QConceptTag.conceptTag.id.in(QProblem.problem.conceptTagIds)) + .where(QProblem.problem.id.in(problemSet.getProblemIds())) + .fetch() + .stream() + .collect( + HashMap::new, + (map, tuple) -> map + .computeIfAbsent(tuple.get(QProblem.problem.id), k -> new HashSet<>()) + .add(tuple.get(QConceptTag.conceptTag.name)), + HashMap::putAll + ); + + // 문제 요약 정보 생성 + List problemSummaries = problemData.stream() + .map(tuple -> ProblemSummaryResponse.builder() + .problemId(tuple.get(QProblem.problem.id)) + .problemCustomId(tuple.get(QProblem.problem.problemCustomId).toString()) + .problemTitle(tuple.get(QProblem.problem.title).toString()) + .memo(tuple.get(QProblem.problem.memo)) + .mainProblemImageUrl(tuple.get(QProblem.problem.mainProblemImageUrl)) + .tagNames(conceptTagMap.getOrDefault(tuple.get(QProblem.problem.id), new HashSet<>())) + .build() + ) + .toList(); + + return ProblemSetGetResponse.of(problemSet, publishedDates, problemSummaries); + } +} \ No newline at end of file diff --git a/src/main/java/com/moplus/moplus_server/domain/problemset/service/ProblemSetGetService.java b/src/main/java/com/moplus/moplus_server/domain/problemset/service/ProblemSetGetService.java index ef66f46..cdf0dfd 100644 --- a/src/main/java/com/moplus/moplus_server/domain/problemset/service/ProblemSetGetService.java +++ b/src/main/java/com/moplus/moplus_server/domain/problemset/service/ProblemSetGetService.java @@ -1,22 +1,11 @@ package com.moplus.moplus_server.domain.problemset.service; -import com.moplus.moplus_server.domain.concept.domain.ConceptTag; -import com.moplus.moplus_server.domain.concept.repository.ConceptTagRepository; -import com.moplus.moplus_server.domain.problem.domain.problem.Problem; -import com.moplus.moplus_server.domain.problem.repository.ProblemRepository; import com.moplus.moplus_server.domain.problemset.domain.ProblemSet; import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse; -import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse; +import com.moplus.moplus_server.domain.problemset.repository.ProblemSetGetRepositoryCustom; import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository; -import com.moplus.moplus_server.admin.publish.domain.Publish; -import com.moplus.moplus_server.domain.publish.repository.PublishRepository; import com.moplus.moplus_server.global.error.exception.BusinessException; import com.moplus.moplus_server.global.error.exception.ErrorCode; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,9 +15,7 @@ public class ProblemSetGetService { private final ProblemSetRepository problemSetRepository; - private final ProblemRepository problemRepository; - private final ConceptTagRepository conceptTagRepository; - private final PublishRepository publishRepository; + private final ProblemSetGetRepositoryCustom problemSetGetRepositoryCustom; @Transactional(readOnly = true) public ProblemSetGetResponse getProblemSet(Long problemSetId) { @@ -36,23 +23,6 @@ public ProblemSetGetResponse getProblemSet(Long problemSetId) { if (problemSet.isDeleted()) { throw new BusinessException(ErrorCode.DELETE_PROBLEM_SET_GET_ERROR); } - List publishedDates = publishRepository.findByProblemSetId(problemSetId).stream() - .map(Publish::getPublishedDate) - .toList(); - - List problemSummaries = new ArrayList<>(); - for (Long problemId : problemSet.getProblemIds()) { - Problem problem = problemRepository.findByIdElseThrow(problemId); - Set tagNames = new HashSet<>( - conceptTagRepository.findAllByIdsElseThrow(problem.getConceptTagIds()) - .stream() - .map(ConceptTag::getName) - .toList()); - problem.getChildProblems().stream() - .map(childProblem -> conceptTagRepository.findAllByIdsElseThrow(childProblem.getConceptTagIds())) - .forEach(conceptTags -> tagNames.addAll(conceptTags.stream().map(ConceptTag::getName).toList())); - problemSummaries.add(ProblemSummaryResponse.of(problem, tagNames)); - } - return ProblemSetGetResponse.of(problemSet, publishedDates, problemSummaries); + return problemSetGetRepositoryCustom.getProblemSet(problemSet); } } From c1345996655d2366c158bc149db5f0543047ebbd Mon Sep 17 00:00:00 2001 From: HongGit Date: Wed, 12 Mar 2025 17:59:45 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[fix/#91]=20=EB=AC=B8=ED=95=AD=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ProblemSetGetRepositoryCustom.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java index d25052b..bd739ff 100644 --- a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java +++ b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java @@ -31,8 +31,8 @@ public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { List problemData = queryFactory .select( QProblem.problem.id, - QProblem.problem.problemCustomId, - QProblem.problem.title, + QProblem.problem.problemCustomId.id, + QProblem.problem.title.title, QProblem.problem.memo, QProblem.problem.mainProblemImageUrl ) @@ -62,8 +62,8 @@ public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { List problemSummaries = problemData.stream() .map(tuple -> ProblemSummaryResponse.builder() .problemId(tuple.get(QProblem.problem.id)) - .problemCustomId(tuple.get(QProblem.problem.problemCustomId).toString()) - .problemTitle(tuple.get(QProblem.problem.title).toString()) + .problemCustomId(tuple.get(QProblem.problem.problemCustomId.id)) + .problemTitle(tuple.get(QProblem.problem.title.title)) .memo(tuple.get(QProblem.problem.memo)) .mainProblemImageUrl(tuple.get(QProblem.problem.mainProblemImageUrl)) .tagNames(conceptTagMap.getOrDefault(tuple.get(QProblem.problem.id), new HashSet<>())) From abab3c3fbf9c25e7276859cde3dd97cce628360a Mon Sep 17 00:00:00 2001 From: HongGit Date: Wed, 12 Mar 2025 18:01:48 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[fix/#91]=20Q=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?import=EB=AC=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProblemSetGetRepositoryCustom.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java index bd739ff..b933e18 100644 --- a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java +++ b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java @@ -1,10 +1,11 @@ package com.moplus.moplus_server.domain.problemset.repository; +import static com.moplus.moplus_server.admin.publish.domain.QPublish.*; +import static com.moplus.moplus_server.domain.concept.domain.QConceptTag.*; +import static com.moplus.moplus_server.domain.problem.domain.problem.QProblem.*; + import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse; import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse; -import com.moplus.moplus_server.admin.publish.domain.QPublish; -import com.moplus.moplus_server.domain.concept.domain.QConceptTag; -import com.moplus.moplus_server.domain.problem.domain.problem.QProblem; import com.moplus.moplus_server.domain.problemset.domain.ProblemSet; import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -22,51 +23,51 @@ public class ProblemSetGetRepositoryCustom { public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { // 발행 날짜 조회 쿼리 List publishedDates = queryFactory - .select(QPublish.publish.publishedDate) - .from(QPublish.publish) - .where(QPublish.publish.problemSetId.eq(problemSet.getId())) + .select(publish.publishedDate) + .from(publish) + .where(publish.problemSetId.eq(problemSet.getId())) .fetch(); // 문제 조회 쿼리 (문제 자체 정보만 조회) List problemData = queryFactory .select( - QProblem.problem.id, - QProblem.problem.problemCustomId.id, - QProblem.problem.title.title, - QProblem.problem.memo, - QProblem.problem.mainProblemImageUrl + problem.id, + problem.problemCustomId.id, + problem.title.title, + problem.memo, + problem.mainProblemImageUrl ) - .from(QProblem.problem) - .where(QProblem.problem.id.in(problemSet.getProblemIds())) + .from(problem) + .where(problem.id.in(problemSet.getProblemIds())) .distinct() .fetch(); // 태그 조회 쿼리 (각 문제별 태그만 조회) Map> conceptTagMap = queryFactory - .select(QProblem.problem.id, QConceptTag.conceptTag.name) - .from(QProblem.problem) - .leftJoin(QConceptTag.conceptTag) - .on(QConceptTag.conceptTag.id.in(QProblem.problem.conceptTagIds)) - .where(QProblem.problem.id.in(problemSet.getProblemIds())) + .select(problem.id, conceptTag.name) + .from(problem) + .leftJoin(conceptTag) + .on(conceptTag.id.in(problem.conceptTagIds)) + .where(problem.id.in(problemSet.getProblemIds())) .fetch() .stream() .collect( HashMap::new, (map, tuple) -> map - .computeIfAbsent(tuple.get(QProblem.problem.id), k -> new HashSet<>()) - .add(tuple.get(QConceptTag.conceptTag.name)), + .computeIfAbsent(tuple.get(problem.id), k -> new HashSet<>()) + .add(tuple.get(conceptTag.name)), HashMap::putAll ); // 문제 요약 정보 생성 List problemSummaries = problemData.stream() .map(tuple -> ProblemSummaryResponse.builder() - .problemId(tuple.get(QProblem.problem.id)) - .problemCustomId(tuple.get(QProblem.problem.problemCustomId.id)) - .problemTitle(tuple.get(QProblem.problem.title.title)) - .memo(tuple.get(QProblem.problem.memo)) - .mainProblemImageUrl(tuple.get(QProblem.problem.mainProblemImageUrl)) - .tagNames(conceptTagMap.getOrDefault(tuple.get(QProblem.problem.id), new HashSet<>())) + .problemId(tuple.get(problem.id)) + .problemCustomId(tuple.get(problem.problemCustomId.id)) + .problemTitle(tuple.get(problem.title.title)) + .memo(tuple.get(problem.memo)) + .mainProblemImageUrl(tuple.get(problem.mainProblemImageUrl)) + .tagNames(conceptTagMap.getOrDefault(tuple.get(problem.id), new HashSet<>())) .build() ) .toList(); From 3456e75ce863c805d1a466325fa585c898c10387 Mon Sep 17 00:00:00 2001 From: HongGit Date: Wed, 12 Mar 2025 18:26:28 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[fix/#91]=20=EC=83=88=EB=81=BC=EB=AC=B8?= =?UTF-8?q?=ED=95=AD=20=EA=B0=9C=EB=85=90=ED=83=9C=EA=B7=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProblemSetGetRepositoryCustom.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java index b933e18..fa46869 100644 --- a/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java +++ b/src/main/java/com/moplus/moplus_server/domain/problemset/repository/ProblemSetGetRepositoryCustom.java @@ -3,6 +3,7 @@ import static com.moplus.moplus_server.admin.publish.domain.QPublish.*; import static com.moplus.moplus_server.domain.concept.domain.QConceptTag.*; import static com.moplus.moplus_server.domain.problem.domain.problem.QProblem.*; +import static com.moplus.moplus_server.domain.problem.domain.childProblem.QChildProblem.*; import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse; import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse; @@ -28,7 +29,7 @@ public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { .where(publish.problemSetId.eq(problemSet.getId())) .fetch(); - // 문제 조회 쿼리 (문제 자체 정보만 조회) + // 문항 및 새끼문항 조회 List problemData = queryFactory .select( problem.id, @@ -38,17 +39,30 @@ public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { problem.mainProblemImageUrl ) .from(problem) + .leftJoin(problem.childProblems, childProblem) // 자식 문제 JOIN .where(problem.id.in(problemSet.getProblemIds())) .distinct() .fetch(); - // 태그 조회 쿼리 (각 문제별 태그만 조회) + // 문항 및 새끼 문항의 개념 태그 조회 + List allProblemIds = problemSet.getProblemIds(); // 문제 ID 목록 + List childProblemIds = queryFactory + .select(childProblem.id) + .from(problem) + .join(problem.childProblems, childProblem) + .where(problem.id.in(allProblemIds)) + .fetch(); + + Set allProblemAndChildProblemIds = new HashSet<>(allProblemIds); + allProblemAndChildProblemIds.addAll(childProblemIds); // 문제 + 자식 문제 ID 합침 + + // 문항 및 자식 문항의 개념 태그 조회 Map> conceptTagMap = queryFactory .select(problem.id, conceptTag.name) .from(problem) .leftJoin(conceptTag) .on(conceptTag.id.in(problem.conceptTagIds)) - .where(problem.id.in(problemSet.getProblemIds())) + .where(problem.id.in(allProblemAndChildProblemIds)) // 문제 + 자식 문제 ID .fetch() .stream() .collect( @@ -59,7 +73,6 @@ public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { HashMap::putAll ); - // 문제 요약 정보 생성 List problemSummaries = problemData.stream() .map(tuple -> ProblemSummaryResponse.builder() .problemId(tuple.get(problem.id)) @@ -67,7 +80,7 @@ public ProblemSetGetResponse getProblemSet(ProblemSet problemSet) { .problemTitle(tuple.get(problem.title.title)) .memo(tuple.get(problem.memo)) .mainProblemImageUrl(tuple.get(problem.mainProblemImageUrl)) - .tagNames(conceptTagMap.getOrDefault(tuple.get(problem.id), new HashSet<>())) + .tagNames(conceptTagMap.getOrDefault(tuple.get(problem.id), new HashSet<>())) // 태그 매핑 .build() ) .toList();