WindsomeProject - 계층형 답글 기능 구현

박민수·2024년 2월 13일
0

WindsomeProject

목록 보기
26/32
post-thumbnail

개요

해당 포스팅에서는 계층형 답글 기능 구현 과정에 대해서 정리해 보고자 한다.
먼저, 계층형 게시글을 구현하기 위해 테이블의 구조를 변경하고 쿼리를 수정했다.
답글의 계층이 계속 추가될 때 최신 답글이 위로 올라오도록 구현했다.

테이블 구조 변경

Qa 테이블에 originNo, groupOrd, groupLayer 필드를 추가했다.

/* Qa.java */

// 새롭게 추가된 필드
private Long originNo; // 원글 번호
private int groupOrd; // 원글(답글 포함)에 대한 순서
private int groupLayer; // 답글 계층

Service 로직 수정

  • 원글 작성 시 originNo를 자신의 id 값으로 설정하고, groupOrd와 groupLayer에 0을 할당합니다.
  • 답글 작성 시 부모글의 originNo를 사용하여 그룹을 설정하고, 그에 따라 groupOrd와 groupLayer를 조정합니다. 최신 답글이 위로 올라오도록 처리됩니다.
/* QaService.java */

public void enrollQa(QaEnrollDto qaEnrollDto, Account account) {
    // Dto -> Entity 변환 후 DB에 저장
    Qa qa = Qa.createQa(qaEnrollDto, account);
    qaRepository.save(qa);

    // 답글 작성인 경우 뷰에서 originNo 값을 전달
    // originNo 값이 0인 경우 원글 작성, 값이 0 이상인 경우 답글 작성
    if (qaEnrollDto.getOriginNo() == 0) {
        qa.initReplyInfo(qa.getId(), 0, 0);
    } else {
        Qa findQa = qaRepository.findById(qaEnrollDto.getOriginNo()).orElseThrow(EntityNotFoundException::new);
        qa.initReplyInfo(findQa.getOriginNo(), findQa.getGroupOrd() + 1, findQa.getGroupLayer() + 1);

        // 답글들 중에 원글 groupOrd 보다 큰 값을 가진 경우, 기존 groupOrd 값에 +1 (최신 답글이 제일 위로 올라옴)
        List<Qa> qaList = qaRepository.findByOriginNoAndGroupOrdGreaterThan(findQa.getOriginNo(), findQa.getGroupOrd());
        qaList.forEach(post -> { post.setGroupOrd(post.getGroupOrd() + 1); qaRepository.save(post);});
    }
    qaRepository.save(qa);
}

쿼리 수정

QueryDsl을 사용하여 동적 쿼리를 작성하였다.
originNo를 기준으로 내림차순으로 정렬하고, groupOrd를 오름차순으로 정렬한다.

/* QaRepositoryCustomImpl.java */

@Override
public Page<QaListDto> getQaList(QaSearchDto qaSearchDto, Pageable pageable) {
    QQa qa = QQa.qa;

    List<QaListDto> content = queryFactory
            .select(
                    new QQaListDto(
                            qa.id,
                            qa.title,
                            qa.account.name,
                            qa.regTime,
                            qa.secretYN,
                            qa.originNo,
                            qa.groupOrd,
                            qa.groupLayer
                    )
            )
            .from(qa)
            .where(like(qaSearchDto))
            .orderBy(qa.originNo.desc(), qa.groupOrd.asc())
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            .fetch();

    JPAQuery<Long> total = queryFactory
            .select(qa.count())
            .from(qa)
            .where(like(qaSearchDto));

    return PageableExecutionUtils.getPage(content, pageable, total::fetchOne);
}

실제 동작

  • 사용자가 검색한 검색어에 따라 동적 쿼리가 실행되어 검색 결과가 표시된다.
  • 답글은 최신 순서로 상단에 표시되며, 계층적으로 표시된다.


참조

profile
안녕하세요 백엔드 개발자입니다.

0개의 댓글

관련 채용 정보