From 7489ff2bdec391c03c991e638af75d2aae2a28e0 Mon Sep 17 00:00:00 2001 From: dmori Date: Thu, 29 May 2025 00:14:32 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[Add]=20QuizSession=EA=B3=BC=20UserAnswer?= =?UTF-8?q?=EA=B0=84=20=EC=96=91=EB=B0=A9=ED=96=A5=20=EB=A7=A4=ED=95=91=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spring_rest_api/entity/QuizSession.java | 21 +++++++++++++++++++ .../_1/spring_rest_api/entity/UserAnswer.java | 11 ++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java b/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java index 1883e72..468d5a2 100644 --- a/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java +++ b/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java @@ -4,11 +4,14 @@ import com._1.spring_rest_api.entity.base.BaseTimeEntity; import jakarta.persistence.*; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity @Table(name = "QUIZ_SESSION") @@ -31,6 +34,10 @@ public class QuizSession extends BaseTimeEntity { @JoinColumn(name = "quiz_id") private CustomQuiz quiz; + @OneToMany(mappedBy = "quizSession", cascade = CascadeType.ALL) + @Builder.Default + private List userAnswers = new ArrayList<>(); + private Integer currentQuestionIndex; private Boolean completed; @@ -53,6 +60,20 @@ public void changeQuiz(CustomQuiz quiz) { } } + public void addUserAnswer(UserAnswer userAnswer) { + this.userAnswers.add(userAnswer); + if (userAnswer.getQuizSession() != this) { + userAnswer.changeQuizSession(this); + } + } + + public void removeUserAnswer(UserAnswer userAnswer) { + this.userAnswers.remove(userAnswer); + if (userAnswer.getQuizSession() == this) { + userAnswer.changeQuizSession(null); + } + } + public static QuizSession create(User user, CustomQuiz quiz) { if (user == null) { throw new IllegalArgumentException("사용자는 null이 될 수 없습니다"); diff --git a/src/main/java/com/_1/spring_rest_api/entity/UserAnswer.java b/src/main/java/com/_1/spring_rest_api/entity/UserAnswer.java index d3de980..c6539f9 100644 --- a/src/main/java/com/_1/spring_rest_api/entity/UserAnswer.java +++ b/src/main/java/com/_1/spring_rest_api/entity/UserAnswer.java @@ -31,6 +31,10 @@ public class UserAnswer extends BaseTimeEntity { @JoinColumn(name = "user_id") private User user; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "quiz_session_id") + private QuizSession quizSession; // 추가 + @Column(name = "user_answer", columnDefinition = "TEXT") private String userAnswer; @@ -58,4 +62,11 @@ public void changeQuestion(Question question) { question.getUserAnswers().add(this); } } + + public void changeQuizSession(QuizSession quizSession) { + this.quizSession = quizSession; + if (quizSession != null && !quizSession.getUserAnswers().contains(this)) { + quizSession.getUserAnswers().add(this); + } + } } \ No newline at end of file From c466483e4754e12190c100a4cc3c6c46ac02ea19 Mon Sep 17 00:00:00 2001 From: dmori Date: Thu, 29 May 2025 00:28:26 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[Add]=20=EB=8B=B5=EB=B3=80=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=20=EC=8B=9C=20QuizSession=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=8F=84=20=ED=95=A8=EA=BB=98=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/_1/spring_rest_api/entity/QuizSession.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java b/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java index 468d5a2..773a4d9 100644 --- a/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java +++ b/src/main/java/com/_1/spring_rest_api/entity/QuizSession.java @@ -101,12 +101,14 @@ public UserAnswer createAnswer(String userAnswerText) { UserAnswer userAnswer = UserAnswer.builder() .user(this.user) .question(currentQuestion) + .quizSession(this) .userAnswer(userAnswerText) .isCorrect(isCorrect) .attemptCount(1) .answeredAt(LocalDateTime.now()) .build(); + this.addUserAnswer(userAnswer); currentQuestion.addUserAnswer(userAnswer); this.user.addUserAnswer(userAnswer); From 8aea71a79e131c9ed6edb5fe946522e436f6cb55 Mon Sep 17 00:00:00 2001 From: dmori Date: Thu, 29 May 2025 00:37:43 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[Add]=20=EC=84=B8=EC=85=98=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=B0=A9=EC=8B=9D=20sessionId=EB=A5=BC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/UserAnswerRepository.java | 16 ++-------------- .../service/QuizSessionQueryServiceImpl.java | 19 +++---------------- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/_1/spring_rest_api/repository/UserAnswerRepository.java b/src/main/java/com/_1/spring_rest_api/repository/UserAnswerRepository.java index 6733bb7..d2ad425 100644 --- a/src/main/java/com/_1/spring_rest_api/repository/UserAnswerRepository.java +++ b/src/main/java/com/_1/spring_rest_api/repository/UserAnswerRepository.java @@ -12,18 +12,6 @@ @Repository public interface UserAnswerRepository extends JpaRepository { - /** - * 특정 사용자의 모든 답변을 조회합니다. - * - * @param userId 사용자 ID - * @return 사용자 답변 목록 - */ - @Query("SELECT a FROM UserAnswer a WHERE a.user.id = :userId ORDER BY a.answeredAt DESC") - List findAllByUserId(@Param("userId") Long userId); - - - @Query("SELECT ua FROM UserAnswer ua WHERE ua.user.id = :userId AND ua.question.id IN :questionIds") - List findByUserIdAndQuestionIdIn( - @Param("userId") Long userId, - @Param("questionIds") Collection questionIds); + @Query("SELECT ua FROM UserAnswer ua WHERE ua.quizSession.id = :sessionId ORDER BY ua.answeredAt ASC") + List findByQuizSessionIdOrderByAnsweredAt(@Param("sessionId") Long sessionId); } \ No newline at end of file diff --git a/src/main/java/com/_1/spring_rest_api/service/QuizSessionQueryServiceImpl.java b/src/main/java/com/_1/spring_rest_api/service/QuizSessionQueryServiceImpl.java index c84ebb8..0e78be5 100644 --- a/src/main/java/com/_1/spring_rest_api/service/QuizSessionQueryServiceImpl.java +++ b/src/main/java/com/_1/spring_rest_api/service/QuizSessionQueryServiceImpl.java @@ -45,30 +45,17 @@ public QuizSessionDetailResponse getSessionDetail(Long sessionId) { QuizSession session = quizSessionRepository.findById(sessionId) .orElseThrow(() -> new EntityNotFoundException("Session not found with id: " + sessionId)); - List userAnswerResponses = getUserAnswersForSession(session); + List userAnswerResponses = getUserAnswersForSession(sessionId); return quizSessionDetailConverter.toDto(session, userAnswerResponses); } - private List getUserAnswersForSession(QuizSession session) { - CustomQuiz quiz = session.getQuiz(); - Long userId = session.getUser().getId(); - - // 퀴즈에 포함된 질문 ID 집합 추출 - Set quizQuestionIds = getQuizQuestionIds(quiz); - - List userAnswers = userAnswerRepository.findByUserIdAndQuestionIdIn( - userId, quizQuestionIds); + private List getUserAnswersForSession(Long sessionId) { + List userAnswers = userAnswerRepository.findByQuizSessionIdOrderByAnsweredAt(sessionId); // DTO로 변환 return userAnswers.stream() .map(userAnswerConverter::toDto) .collect(Collectors.toList()); } - - private Set getQuizQuestionIds(CustomQuiz quiz) { - return quiz.getQuizQuestionMappings().stream() - .map(mapping -> mapping.getQuestion().getId()) - .collect(Collectors.toSet()); - } }