Spring/[P] AI 챗봇 기반 맞춤형 레시피 서비스

[SpringBoot/Querydsl] QnA 대댓글 (3) 조회

alsruds 2024. 3. 5. 13:35

 

Querydsl 을 이용하여, 작성한 대댓글 형식의 QnA 를 조회해봅시다 ~

 

 


 

[ QnA 조회하기 ]

 

0. QnA 작성하기

2024.03.04 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/Querydsl] QnA 대댓글 (2) 작성

 

[SpringBoot/Querydsl] QnA 대댓글 (2) 작성

대댓글 형식의 QnA 를 작성해봅시다 ~ [ QnA 작성하기 ] 0. Querydsl 설정 2024.03.01 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/Querydsl] 대댓글 Querydsl (1) 프로젝트 설정 [SpringBoot/Querydsl]

alsrudalsrudalsrud.tistory.com

 

1. Controller

@RestController
@RequestMapping("/post")
@RequiredArgsConstructor
public class QnaController {

    private final QnaService qnaService;
    
    ...

    // Qna 조회
    @GetMapping("/{postId}/qna")
    public ApiResponse<List<QnaResponseDTO.getQnaDTO>> getQna(@PathVariable("postId") Long postId) {

        List<QnaResponseDTO.getQnaDTO> qnaList = qnaService.getQna(postId);
        return ApiResponse.onSuccess(qnaList);
    }
}

 

· 조회하려는 QnA 의 게시글 id 를 받아 넘겨주기

 

2. Service

@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class QnaServiceImpl implements QnaService {

    ...
    
    // Qna 조회
    @Override
    public List<QnaResponseDTO.getQnaDTO> getQna(Long postId) {

        // 해당 커뮤니티 게시글
        Post post = postRepository.findById(postId).orElseThrow(() -> new GeneralException(ErrorStatus.POST_NOT_FOUND));

        // QueryDSL 을 사용하여 게시글 Qna 전체 조회 (정렬 : 부모 댓글 순, 작성시간 순)
        List<Qna> qnaList = qnaCustomRepository.findAllByPost(post);

        // 대댓글 중첩구조 세팅
        List<QnaResponseDTO.getQnaDTO> qnaResponseDTOList = new ArrayList<>();
        Map<Long, QnaResponseDTO.getQnaDTO> map = new HashMap<>();

        qnaList.forEach(q -> {
                QnaResponseDTO.getQnaDTO qdto = QnaConverter.getQnaResult(q);
                map.put(qdto.getQnaId(), qdto);
                if (q.getParent() != null) map.get(q.getParent().getId()).getChildren().add(qdto);
                else qnaResponseDTOList.add(qdto);
                }
        );

        return qnaResponseDTOList;
    }
}

 

· Querydsl 을 사용한 CustomRepository 를 이용하여 해당 게시글의 QnA 관련 글 조회하기

 

3. Repository

@Repository
@RequiredArgsConstructor
public class QnaCustomRepository {

    private final JPAQueryFactory jpaQueryFactory;

    // 커뮤니티 게시글 Qna 댓글 전체 가져오기
    public List<Qna> findAllByPost(Post post) {
        return jpaQueryFactory.selectFrom(qna)
                .leftJoin(qna.parent)
                .fetchJoin()
                .where(qna.post.id.eq(post.getId()))
                .orderBy(qna.parent.id.asc().nullsFirst(), qna.createdAt.asc())
                .fetch();
    }
}

 

· QuerydslConfig 로 주입했던 JPAQueryFactory 를 이용하여 조회하기

 

4. DTO

public class QnaResponseDTO {

    // Qna 조회
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    public static class getQnaDTO {

        ...

        @Schema(description = "자식 댓글 리스트")
        private List<QnaResponseDTO.getQnaDTO> children = new ArrayList<>();

        public getQnaDTO(Long qnaId, Long memberId, String memberNickName, String memberImage,
                         LocalDateTime createdAt, String content, String imageUrl) {
            this.qnaId = qnaId;
            this.memberId = memberId;
            this.memberNickName = memberNickName;
            this.memberImage = memberImage;
            this.createdAt = createdAt;
            this.content = content;
            this.imageUrl = imageUrl;
        }
    }
}

 

· 자식 댓글 리스트가 있을 때만 반환할 수 있도록 getQnaDTO 만들어주기