댓글 컨트롤러와 서비스 틀 만들기
@RestController // REST 컨트롤러 선언
public class CommentApiController {
@Autowired
private CommentService commentService; // 댓글 서비스 객체 주입
@Service // 서비스로 선언
public class CommentService {
@Autowired
private CommentRepository commentRepository; // 댓글 리파지터라 객체 주입
@Autowired
private ArticleRepository articleRepository; // 게시글 리파지터라 객체 주입
public class CommentApiController {
@Autowired
private CommentService commentService;
// 1. 댓글 조회
// 2. 댓글 생성
// 3. 댓글 수정
// 4. 댓글 삭제
}
댓글 조회하기
1. 요청을 받아 응답할 컨트롤러 만들기
// 1. 댓글 조회
@GetMapping("/api/articles/{articleId}/comments") // 댓글 조회 요청 접수
public ResponseEntity<List<CommentDto>> comments(@PathVariable Long articleId) { // comments() 메서드 생성
// 서비스에게 작업 위임
List<CommentDto> dtos = commentService.comments(articleId);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(dtos);
}
@AllArgsConstructor // 모든 필드를 파라미터로 갖는 생성자 자동 생성
@NoArgsConstructor // 파라미터가 아예 없는 기본 생성자 자동 생성
@Getter // 각 필드 값을 조회할 수 있는 getter 메서드 자동 생성
@ToString // 모든 필드를 출력할 수 있는 toString 메서드 자동 생성
public class CommentDto {
private Long id; // 댓글의 id
private Long articleId; // 댓글의 부모 id
private String nickname; // 댓글 작성자
private String body; // 댓글 본문
2. 요청을 처리할 서비스 만들기
public List<CommentDto> comments(Long articleId) {
// 1. 댓글 조회
List<Comment> comments = commentRepository.findByArticleId(articleId);
// 2. 엔티티 -> DTO 변환
List<CommentDto> dtos = new ArrayList<CommentDto>();
for (int i = 0; i < comments.size(); i++) { // 조회한 댓글 엔티티 수만큼 반복
Comment c = comments.get(i); // 조회한 댓글 엔티티 하나씩 가져오기
CommentDto dto = CommentDto.createCommentDto(c); // 엔티티를 DTO로 변환
dtos.add(dto); // 변환한 DTO를 dtos 리스트에 삽입
}
// 3. 결과 반환
return dtos;
}
public static CommentDto createCommentDto(Comment comment) {
return new CommentDto(
comment.getId(), // 댓글 엔티티의 id
comment.getArticle().getId(), // 댓글 엔티티가 속한 부모 게시글의 id
comment.getNickname(), // 댓글 엔티티의 nickname
comment.getBody() // 댓글 엔티티의 body
);
}
3. 결과 확인하기
public List<CommentDto> comments(Long articleId) {
/*// 1. 댓글 조회
List<Comment> comments = commentRepository.findByArticleId(articleId);
// 2. 엔티티 -> DTO 변환
List<CommentDto> dtos = new ArrayList<CommentDto>();
for (int i = 0; i < comments.size(); i++) {
Comment c = comments.get(i);
CommentDto dto = CommentDto.createCommentDto(c);
dtos.add(dto);
}*/
// 3. 결과 반환
return commentRepository.findByArticleId(articleId)
.stream()
.map(comment -> CommentDto.createCommentDto(comment))
.collect(Collectors.toList());
}
댓글 생성하기
1. 요청을 받아 응답할 컨트롤러 만들기
// 서비스에게 위임
CommentDto createdDto = commentService.create(articleId, dto);
// 결과 응답
return ResponseEntity.status(HttpStatus.OK).body(createdDto);
2. 요청을 처리할 서비스 만들기
@Transactional // 어노테이션 추가
public CommentDto create(Long articleId, CommentDto dto) {
// 1. 게시글 조회 및 예외 발생
Article article = articleRepository.findById(articleId) // 부모 게시글 가져오기
.orElseThrow(() -> new IllegalArgumentException("댓글 생성 실패! " +
"대상 게시글이 없습니다.")); // 없으면 에러 메시지 출력
// 2. 댓글 엔티티 생성
Comment comment = Comment.createComment(dto, article);
// 3. 댓글 엔티티를 DB로 저장
Comment created = commentRepository.save(comment);
// 4. DTO로 변환하여 반환
return CommentDto.createCommentDto(created);
}
public static Comment createComment(CommentDto dto, Article article) {
// 예외 발생
if (dto.getId() != null)
throw new IllegalArgumentException("댓글 생성 실패! 댓글의 id가 없어야 합니다.");
if (dto.getArticleId() != article.getId())
throw new IllegalArgumentException("댓글 생성 실패! 게시글의 id가 잘못됐습니다.");
// 엔티티 생성 및 반환
return new Comment(
dto.getId(), // 댓글 아이디
article, // 부모 게시글
dto.getNickname(), // 댓글 닉네임
dto.getBody() // 댓글 본문
);
}