해당 포스팅에서는 계층형 답글 기능 구현 과정에 대해서 정리해 보고자 한다.
먼저, 계층형 게시글을 구현하기 위해 테이블의 구조를 변경하고 쿼리를 수정했다.
답글의 계층이 계속 추가될 때 최신 답글이 위로 올라오도록 구현했다.
Qa 테이블에 originNo, groupOrd, groupLayer 필드를 추가했다.
/* Qa.java */
// 새롭게 추가된 필드
private Long originNo; // 원글 번호
private int groupOrd; // 원글(답글 포함)에 대한 순서
private int 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);
}
참조