Querydsl 을 이용하여, 작성했던 QnA 를 삭제해봅시다 ~
[ QnA 삭제하기 ]
0. QnA 작성하기
2024.03.04 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/Querydsl] QnA 대댓글 (2) 작성
1. Controller
@RestController
@RequestMapping("/post")
@RequiredArgsConstructor
public class QnaController {
...
// Qna 삭제
@DeleteMapping("/qna/{qnaId}")
public ApiResponse<QnaResponseDTO.deleteQnaDTO> deleteQna(@PathVariable("qnaId") Long qnaId) {
qnaService.deleteQna(qnaId);
return ApiResponse.onSuccess(QnaConverter.deleteQnaResult());
}
}
· 삭제할 글 id 넘겨주기
2. Service
@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class QnaServiceImpl implements QnaService {
...
// Qna 삭제
@Override
public void deleteQna(Long qnaId) {
// 부모 댓글과 함께 조회
Qna qna = qnaCustomRepository.findQnaByIdWithParent(qnaId).orElseThrow(() -> new GeneralException(ErrorStatus.POST_QNA_NOT_FOUND));
if (!qna.getChildren().isEmpty()) { // 자식이 있을 때
// isDeleted 상태만 변경
qna.changeIsDeleted(true);
// S3 사진 삭제
if (qna.getImageUrl() != null) {
s3Service.deleteImage(qna.getFileName(), "images");
}
} else { // 자식 댓글이 없을 때
// 삭제 가능한 조상 댓글 삭제
qnaRepository.delete(getDeletableAncestorQna(qna));
// S3 사진 삭제
if (qna.getImageUrl() != null) {
s3Service.deleteImage(qna.getFileName(), "images");
}
}
}
private Qna getDeletableAncestorQna(Qna qna) {
// 현재 댓글의 부모
Qna parent = qna.getParent();
// 재귀 : 부모 댓글이 있음 & 부모의 자식 댓글이 1개 & 부모의 삭제 상태가 True
if (parent != null && parent.getChildren().size() == 1 && parent.getIsDeleted()) {
return getDeletableAncestorQna(parent);
}
// 삭제해야 하는 댓글 반환
return qna;
}
}
· 자식 댓글이 있으면 isDeleted 상태만 변경하기
· 모든 부모 댓글을 함께 조회하여, 맨 마지막 댓글이 삭제됐을 때 삭제되지 않은 부모 댓글 직전까지 모두 함께 삭제하기
3. Repository
@Repository
@RequiredArgsConstructor
public class QnaCustomRepository {
private final JPAQueryFactory jpaQueryFactory;
...
// Qna 댓글 삭제
public Optional<Qna> findQnaByIdWithParent(Long qnaId) {
Qna selectedQna = jpaQueryFactory.select(qna)
.from(qna)
.leftJoin(qna.parent).fetchJoin()
.where(qna.id.eq(qnaId))
.fetchOne();
return Optional.ofNullable(selectedQna);
}
}
· 삭제하려는 qna id 가 자식 댓글인, 모든 부모 댓글 함께 조회하기
4. 대댓글을 마무리하며..
🐳 항상 JpaRepository 를 상속받아 쿼리를 사용하다가, Querydsl 을 사용하니 새로웠다
결과적으로는, 프론트 측에서 children 리스트를 처리하기가 어렵다고 판단해 다 갈아엎었다
나도 처음 해봐서 시간을 꽤나 들였는데.. 없어져서 아쉬웠다ㅎ (울면서 지웠음)
📌 참고한 블로그
https://velog.io/@korea3611/Spring-Boot-대댓글-기능-만들기
https://velog.io/@tjddnths0223/스프링부트JPAqueryDsl-대댓글계층형-구현
'Spring > [P] AI 챗봇 기반 맞춤형 레시피 서비스' 카테고리의 다른 글
[AWS ElasticBeanstalk/GitHub Action] CI/CD 구축 (2) GitHub Action Secrets 등록하기 (0) | 2024.03.13 |
---|---|
[AWS ElasticBeanstalk/GitHub Action] CI/CD 구축 (1) 배포 스크립트 작성하기 (0) | 2024.03.12 |
[SpringBoot/Querydsl] QnA 대댓글 (3) 조회 (2) | 2024.03.05 |
[SpringBoot/Querydsl] QnA 대댓글 (2) 작성 (2) | 2024.03.04 |
[SpringBoot/Querydsl] QnA 대댓글 (1) Querydsl 프로젝트 설정 (0) | 2024.03.01 |