[개인과제] 숙련 주차

신성훈·2024년 6월 3일
0

TIL

목록 보기
30/162
post-thumbnail
  • 요구 사항

    1. 일정과 댓글의 연관 관계
      지난 과제에서 만든 일정에 댓글을 추가할 수 있습니다.
      ERD에도 댓글 모델을 추가합니다.
      각 일정에 댓글을 작성할 수 있도록 관련 클래스를 추가하고 연관 관계를 설정합니다.
      매핑 관계를 설정합니다. (1:1 or N:1 or N:M)

    2. 댓글 등록
      -기능
      선택한 일정이 있다면 댓글을 등록합니다.

      -조건
      댓글이 등록되었다면 client에게 반환합니다.
      선택한 일정이 DB에 저장되어 있어야 합니다.
      댓글을 식별하는 고유번호, 댓글 내용, 댓글을 작성한 사용자 아이디, 댓글이 작성된 일정 아이디, 작성일자를 저장할 수 있습니다.

      ⚠️ 예외 처리
      선택한 일정의 ID를 입력 받지 않은 경우
      댓글 내용이 비어 있는 경우
      일정이 DB에 저장되지 않은 경우

    3. 댓글 수정
      -기능
      선택한 일정의 댓글을 수정합니다.

      -조건
      댓글이 수정되었다면 수정된 댓글을 반환합니다.
      댓글 내용만 수정 가능합니다.
      선택한 일정과 댓글이 DB에 저장되어 있어야 합니다.

      ⚠️ 예외 처리
      선택한 일정이나 댓글의 ID를 입력 받지 않은 경우
      일정이나 댓글이 DB에 저장되지 않은 경우
      선택한 댓글의 사용자가 현재 사용자와 일치하지 않은 경우

    4. 댓글 삭제
      -기능
      선택한 일정의 댓글을 삭제합니다.

      -조건
      성공했다는 메시지와 상태 코드 반환하기
      선택한 일정과 댓글이 DB에 저장되어 있어야 합니다.

      ⚠️ 예외 처리
      선택한 일정이나 댓글의 ID를 입력받지 않은 경우
      일정이나 댓글이 DB에 저장되지 않은 경우
      선택한 댓글의 사용자가 현재 사용자와 일치하지 않은 경우

  • Entity

package com.sparta.homework2.entity;

import com.sparta.homework2.dto.CommentRequestDTO;
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;

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

    @NotEmpty(message = "공백이거나 null인 것은 불가합니다.")
    private String comment;

    @Column(length = 100)
    @Email
    private Long userId;

    private LocalDateTime createdAt;

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

    public Comment(Todo todo, CommentRequestDTO commentRequestDTO) {
        this.comment = commentRequestDTO.getComment();
        this.userId = commentRequestDTO.getUserId();
        this.createdAt = LocalDateTime.now();
        this.todo = todo;

    }

    public void updateComment(CommentRequestDTO requestDTO){
        this.comment = requestDTO.getComment();
    }

}



  • Controller
package com.sparta.homework2.controller;

import com.sparta.homework2.dto.CommentRequestDTO;
import com.sparta.homework2.dto.CommentResponseDTO;
import com.sparta.homework2.entity.Comment;
import com.sparta.homework2.service.CommentService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class CommentController {

    private final CommentService commentService;

    @PostMapping("/comment/{todoId}")
    public CommentResponseDTO createComment(@PathVariable Long todoId, @RequestBody @Valid CommentRequestDTO requestDTO){

        return commentService.createComment(todoId, requestDTO);
    }
    @PutMapping("/comment/{todoId}/{commentId}")
    public CommentResponseDTO updateComment(@PathVariable Long todoId, @PathVariable Long commentId, @RequestBody CommentRequestDTO requestDTO){

        return commentService.updateComment(todoId, commentId, requestDTO);
    }

    @DeleteMapping("/comment/{todoId}/{commentId}")
    public ResponseEntity<String> deleteComment(@PathVariable Long todoId, @PathVariable Long commentId, @RequestHeader Long userId) {

        commentService.deleteComment(todoId, commentId, userId);
        return new ResponseEntity<>("댓글 삭제 성공했습니다.", HttpStatusCode.valueOf(201));
    }

}



  • Service
package com.sparta.homework2.service;

import com.sparta.homework2.dto.CommentRequestDTO;
import com.sparta.homework2.dto.CommentResponseDTO;
import com.sparta.homework2.entity.Comment;
import com.sparta.homework2.entity.Todo;
import com.sparta.homework2.repository.CommentRepository;
import com.sparta.homework2.repository.TodoRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Service
@RequiredArgsConstructor
public class CommentService {

    private final CommentRepository commentRepository;
    private final TodoRepository todoRepository;

    public CommentResponseDTO createComment(Long todoId, CommentRequestDTO requestDTO) {
        Todo todo = todoRepository.findById(todoId).orElseThrow(
                () -> new IllegalArgumentException("선택한 일정이 없습니다.")
        );

        Comment comment = new Comment(todo, requestDTO);
        commentRepository.save(comment);
        return new CommentResponseDTO(comment);
    }


    @Transactional
    public CommentResponseDTO updateComment(Long todoId, Long commentId, CommentRequestDTO requestDTO) {
        todoRepository.findById(todoId).orElseThrow(
                () -> new IllegalArgumentException("선택한 일정이 없습니다.")
        );

        Comment comment = commentRepository.findById(commentId).orElseThrow(
                () -> new IllegalArgumentException("조회한 댓글이 없습니다.")
        );

        if (comment.getUserId().equals(requestDTO.getUserId())) {
            comment.updateComment(requestDTO);
        } else {
            throw new IllegalArgumentException("사용자 ID가 일치하지 않습니다.");

        }
        return new CommentResponseDTO(comment);
    }

    public void deleteComment(Long todoId, Long commentId, Long userId) {

        todoRepository.findById(todoId).orElseThrow(
                () -> new IllegalArgumentException("선택한 일정이 없습니다.")
        );
        Comment comment = commentRepository.findById(commentId).orElseThrow(
                () -> new IllegalArgumentException("조회한 댓글이 없습니다.")
        );

        if (comment.getUserId().equals(userId)) {
            commentRepository.delete(comment);
        } else {
            throw new IllegalArgumentException("사용자 ID가 일치하지 않습니다.");

        }

    }
}



  • Repository
package com.sparta.homework2.repository;

import com.sparta.homework2.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CommentRepository extends JpaRepository<Comment, Long> {
}



[Dto]

  • CommentRequestDto
package com.sparta.homework2.dto;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;

@Getter
@Setter
public class CommentRequestDTO {
    private String comment;
    private Long userId;
    private Long todoId;
}

  • CommentResposeDto
package com.sparta.homework2.dto;

import com.sparta.homework2.entity.Comment;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@NoArgsConstructor
public class CommentResponseDTO {
    private Long userId;
    private String comment;
    private LocalDateTime createdAt;

    public CommentResponseDTO(Comment comment) {
        this.userId = comment.getUserId();
        this.comment = comment.getComment();
        this.createdAt = comment.getCreatedAt();
    }
}

📝오늘의 회고

처음 이번 과제로 코드 짜면서 재미를 붙였다.

profile
조급해하지 말고, 흐름을 만들고, 기록하면서 쌓아가자.

0개의 댓글