
Entity
package com.sparta.outsourcing.comment.entity;
import com.sparta.outsourcing.board.entity.Board;
import com.sparta.outsourcing.comment.dto.CommentRequestDTO;
import com.sparta.outsourcing.common.AnonymousNameGenerator;
import com.sparta.outsourcing.common.Timestamped;
import com.sparta.outsourcing.user.entity.User;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Entity
@Getter
@NoArgsConstructor
@Table(name = "comments")
public class Comment extends Timestamped {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "공백이거나 null인 것은 불가합니다.")
@Column(name = "comment", nullable = false)
private String comment;
@ManyToOne
@JoinColumn(name = "board_id")
private Board board;
private String generatedname;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Column(name = "likes")
private Long like;
public Comment(Board board, CommentRequestDTO commentRequestDTO, User user){
this.board = board;
this.comment = commentRequestDTO.getComment();
this.generatedname = AnonymousNameGenerator.nameGenerate();
this.user = user;
this.like = 0L;
}
public void updateComment(CommentRequestDTO requestDTO) {
this.comment = requestDTO.getComment();
}
public void decreaseLike() {
this.like--;
}
public void increaseLike() {
this.like++;
}
}
Controller
package com.sparta.outsourcing.comment.controller;
import com.sparta.outsourcing.comment.dto.CommentRequestDTO;
import com.sparta.outsourcing.comment.dto.CommentResponseDTO;
import com.sparta.outsourcing.comment.service.CommentService;
import com.sparta.outsourcing.security.UserDetailsImpl;
import com.sparta.outsourcing.user.dto.CommonResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class CommentController {
private final CommentService commentService;
//Comment 전체 조회
@GetMapping("/boards/{boardId}/comments")
public ResponseEntity<CommonResponse<List<CommentResponseDTO>>> viewAllComment(@PathVariable(value = "boardId") Long boardId) {
List<CommentResponseDTO> responseDTOList = commentService.viewAllComment(boardId);
CommonResponse<List<CommentResponseDTO>> response = new CommonResponse<>("댓글조회 성공", HttpStatus.OK.value(),responseDTOList);
return new ResponseEntity<>(response, HttpStatus.OK);
}
//Comment 작성
@PostMapping("/boards/{boardId}/comments")
public ResponseEntity<CommonResponse<CommentResponseDTO>> createComment(@PathVariable(value = "boardId") Long boardId,
@RequestBody @Valid CommentRequestDTO commentRequestDTO,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
CommentResponseDTO comment = commentService.createComment(boardId, commentRequestDTO, userDetails.getUser());
CommonResponse<CommentResponseDTO> response = new CommonResponse<>("댓글이 작성되었습니다.", HttpStatus.CREATED.value(),comment);
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
//Comment 수정
@PutMapping("/boards/{boardId}/comments/{commentId}")
public ResponseEntity<CommonResponse<CommentResponseDTO>> updateComment(@PathVariable(value = "boardId") Long boardId,
@PathVariable(value = "commentId") Long commentId,
@RequestBody @Valid CommentRequestDTO commentRequestDTO,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
CommentResponseDTO comment = commentService.updateComment(boardId, commentId, commentRequestDTO, userDetails.getUser());
CommonResponse<CommentResponseDTO> response = new CommonResponse<>("댓글 수정이 완료되었습니다.", HttpStatus.OK.value(), comment);
return new ResponseEntity<>(response, HttpStatus.OK);
}
//Comment 삭제
@DeleteMapping("/boards/{boardId}/comments/{commentId}")
public ResponseEntity<String> deleteComment(@PathVariable(value = "boardId") Long boardId,
@PathVariable(value = "commentId") Long commentId,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
commentService.deleteComment(boardId, commentId, userDetails.getUser());
return ResponseEntity.ok("댓글이 삭제 되었습니다.");
}
}
Service
package com.sparta.outsourcing.comment.service;
import com.sparta.outsourcing.board.entity.Board;
import com.sparta.outsourcing.board.repository.BoardRepository;
import com.sparta.outsourcing.comment.dto.CommentRequestDTO;
import com.sparta.outsourcing.comment.dto.CommentResponseDTO;
import com.sparta.outsourcing.comment.entity.Comment;
import com.sparta.outsourcing.comment.repository.CommentRepository;
import com.sparta.outsourcing.exception.ForbiddenException;
import com.sparta.outsourcing.exception.NotFoundException;
import com.sparta.outsourcing.user.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
@Service
@RequiredArgsConstructor
public class CommentService {
private final BoardRepository boardRepository;
private final CommentRepository commentRepository;
//댓글 전체 조회
public List<CommentResponseDTO> viewAllComment(Long boardId) {
boardRepository.findById(boardId).orElseThrow(
() -> new NotFoundException("선택한 게시물이 없습니다.")
);
List<Comment> comments = commentRepository.findAllByBoardId(boardId);
return comments.stream().map(CommentResponseDTO::new).toList();
}
// 댓글 작성
public CommentResponseDTO createComment(Long boardId, CommentRequestDTO commentRequestDTO, User user) {
Board board = boardRepository.findById(boardId).orElseThrow(
() -> new NotFoundException("선택한 게시물이 없습니다.")
);
Comment comment = new Comment(board, commentRequestDTO, user);
Comment saveComment = commentRepository.save(comment);
return new CommentResponseDTO(saveComment);
}
// 댓글 수정
@Transactional
public CommentResponseDTO updateComment(Long boardId,Long commentId, CommentRequestDTO commentRequestDTO, User user) {
boardRepository.findById(boardId).orElseThrow(
() -> new NotFoundException("선택한 게시물이 없습니다.")
);
Comment comment = commentRepository.findById(commentId).orElseThrow(
() -> new NotFoundException("조회한 댓글이 없습니다.")
);
if (Objects.equals(comment.getUser().getUserUid(), user.getUserUid())) {
comment.updateComment(commentRequestDTO);
} else {
throw new NotFoundException("사용자 ID가 일치하지 않습니다.");
}
return new CommentResponseDTO(comment);
}
public void deleteComment(Long boardId, Long commentId, User user) {
boardRepository.findById(boardId).orElseThrow(
() -> new NotFoundException("선택한 게시물이 없습니다.")
);
Comment comment = commentRepository.findById(commentId).orElseThrow(
() -> new NotFoundException("조회한 댓글이 없습니다.")
);
if (Objects.equals(comment.getUser().getUserUid(), user.getUserUid())) {
commentRepository.delete(comment);
} else {
throw new NotFoundException("사용자 ID가 일치하지 않습니다.");
}
}
public void decreaseCommentLike(Long contentId) {
Comment comment = commentRepository.findById(contentId).orElseThrow(() -> new NotFoundException("댓글을 찾을 수 없습니다."));
comment.decreaseLike();
}
public void increaseCommentLike(Long contentId) {
Comment comment = commentRepository.findById(contentId).orElseThrow(() -> new NotFoundException("댓글을 찾을 수 없습니다."));
comment.increaseLike();
}
public void validateCommentLike(Long userId, Long contentId) {
Comment comment = commentRepository.findById(contentId).orElseThrow(() -> new NotFoundException("댓글을 찾을 수 없습니다."));
if(comment.getUser().getId().equals(userId)) {
throw new ForbiddenException("해당 댓글의 작성자입니다.");
}
}
}
Repository
package com.sparta.outsourcing.comment.repository;
import com.sparta.outsourcing.comment.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface CommentRepository extends JpaRepository<Comment, Long> {
List<Comment> findAllByBoardId(Long boardId);
}
DTO
package com.sparta.outsourcing.comment.dto;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
@Getter
public class CommentRequestDTO {
@NotBlank(message = "공백이거나 null인 것은 불가합니다.")
private String comment;
}
package com.sparta.outsourcing.comment.dto;
import com.sparta.outsourcing.comment.entity.Comment;
import lombok.Getter;
@Getter
public class CommentResponseDTO {
private Long id;
private String comment;
private String generatedname;
private Long boardId;
private Long userId;
public CommentResponseDTO(Comment comment) {
this.id = comment.getId();
this.comment = comment.getComment();
this.generatedname = comment.getGeneratedname();
this.boardId = comment.getBoard().getId();
this.userId = comment.getUser().getId();
}
}