24.08.22

윤지현·2024년 8월 22일

TIL

목록 보기
47/75

오늘의 루틴

  • 개인과제 2단계 완료 및 3~4단계 시도 (O)
  • 강의 최소 4개는 듣기 (O)
  • 공부한 내용 복습 (O)

지난번에 했던 내용들에 이어서 개인과제를 도전해봤다.

  • 2단계 : 댓글 CRUD

🔻 조건

  • 일정에 댓글을 달 수 있습니다.
    • 댓글과 일정은 연관관계를 가집니다.
  • 댓글을 저장, 단건 조회, 전체 조회, 수정, 삭제할 수 있습니다.
  • 댓글은 댓글 내용, 작성일, 수정일, 작성 유저명 필드를 갖고 있습니다.

일정과 연관관계를 가지려면 먼저 댓글에 관한 entity, dto, 3 Layer Architecture를 생성해야 한다.
또한 Todo 엔티티도 수정해야한다.


1. Todo.class

Todo 엔티티 수정하는데 1:N으로 연관관계 설정

    @OneToMany(mappedBy = "todo")
    private List<Comment> comments;

2. Comment.class

JPA에서 사용할 entitiy 객체 생성

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "comment")
public class Comment extends Timestamped {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username", nullable = false)
    private String username;
    @Column(name = "content", nullable = false)
    private String content;

    @ManyToOne
    @JoinColumn(name = "todo_id")
    private Todo todo;


    public void update(CommentRequestDto requestDto) {
        this.username = requestDto.getUsername();
        this.content = requestDto.getContent();
    }
}

comment에서 사용할 dto(request, response)도 생성


1. CommentRequestDto.class

package com.sparta.todo.dto;

import lombok.Getter;

@Getter
public class CommentRequestDto {
    private String username;
    private String content;
}

2. CommentRequestDto.class

package com.sparta.todo.dto;

import com.sparta.todo.entity.Comment;
import com.sparta.todo.entity.Todo;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class CommentResponseDto {
    private Long id;
    private String username;
    private String content;
    private LocalDateTime createdAt;
    private LocalDateTime modifiedAt;
    private Long todoId;

    public CommentResponseDto(Comment comment) {
        this.id = comment.getId();
        this.username = comment.getUsername();
        this.content = comment.getContent();
        this.createdAt = comment.getCreatedAt();
        this.modifiedAt = comment.getModifiedAt();
        this.todoId = comment.getTodo().getId();
    }
}

이제는 Comment의 CRUD를 위해 세 가지 계층으로 나누어 개발할 3 Layer Architecture을 생성!


1. CommentController.java

private final CommentService commentService;

    public CommentController(CommentService commentService) {
        this.commentService = commentService;
    }

    @PostMapping("/comment/{todoId}")
    public ResponseEntity<CommentResponseDto> createComment(@PathVariable Long todoId, @RequestBody CommentRequestDto requestDto) {
        return ResponseEntity.status(HttpStatus.CREATED).body(commentService.createComment(todoId, requestDto));
    }

    @GetMapping("/comment/{id}")
    public ResponseEntity<CommentResponseDto> getComment(@PathVariable Long id) {
        return ResponseEntity.status(HttpStatus.OK).body(commentService.getComment(id));
    }

    @GetMapping("/comment")
    public ResponseEntity<List<CommentResponseDto>> getAllComments() {
        return ResponseEntity.status(HttpStatus.OK).body(commentService.getAllComments());
    }

    @PutMapping("/comment/{id}")
    public ResponseEntity<CommentResponseDto> updateComment(@PathVariable Long id, @RequestBody CommentRequestDto requestDto) {
        return ResponseEntity.status(HttpStatus.OK).body(commentService.updateComment(id, requestDto));
    }

    @DeleteMapping("/comment/{id}")
    public ResponseEntity<Void> deleteComment(@PathVariable Long id) {
        commentService.deleteComment(id);
        return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
    }

2. CommentService.java

private final CommentRepository commentRepository;
    private final TodoRepository todoRepository;

    @Transactional
    public CommentResponseDto createComment(Long todoId, CommentRequestDto requestDto) {
        // 해당하는 일정이 있는지 확인
        Todo todo = findTodo(todoId);

        // Comment Entity 생성
        Comment comment = new Comment();
        comment.setUsername(requestDto.getUsername());
        comment.setContent(requestDto.getContent());
        comment.setTodo(todo);


        // DB에 저장
        Comment newcomment = commentRepository.save(comment);

        // Entity -> ResponseDto
        CommentResponseDto commentResponseDto = new CommentResponseDto(newcomment);

        return commentResponseDto;

    }

3. CommentRepository.java

public interface CommentRepository extends JpaRepository<Comment, Long> {
    List<Comment> findAllByOrderByModifiedAtDesc();
}

또한 일정에서 댓글을 작성할 수 있어야 하므로 Todo의 Controller, Serivce에 추가


1. TodoController.java

    @PostMapping("/todo/comment/{id}")
    public ResponseEntity<CommentResponseDto> createCommentToTodo(@PathVariable Long id, @RequestBody CommentRequestDto requestDto) {
        return ResponseEntity.status(HttpStatus.CREATED).body(todoService.createCommentToTodo(id, requestDto));
    }

2. TodoService.java

@Transactional
    public CommentResponseDto createCommentToTodo(Long id, CommentRequestDto requestDto) {
        // Todo Entity가 있는지 확인
        Todo todo = findTodo(id);

        // Comment Entity 생성
        Comment comment = new Comment();
        comment.setUsername(requestDto.getUsername());
        comment.setContent(requestDto.getContent());
        comment.setTodo(todo);

        // DB에 저장
        Comment newcomment = commentRepository.save(comment);

        CommentResponseDto commentResponseDto = new CommentResponseDto(newcomment);

        return commentResponseDto;
    }

Todo에서도, Comment에서도 댓글이 저장된다.

profile
첫 시작

0개의 댓글