24.06.07 금 TIL(Today I Learned)

신민금·2024년 6월 10일
0
post-thumbnail

TIL(Today I Learned)

: 매일 저녁, 하루를 마무리하며 작성 !
: ⭕ 지식 위주, 학습한 것을 노트 정리한다고 생각하고 작성하면서 머리 속 흩어져있는 지식들을 정리 !


알고리즘 코드카타

  • 문제 설명
    문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
  • 제한사항
    strings는 길이 1 이상, 50이하인 배열입니다.
    strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
    strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
    모든 strings의 원소의 길이는 n보다 큽니다.
    인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        String[] answer = new String[strings.length];
        List<String> list = new ArrayList<>();
        
        for(int i = 0; i < strings.length; i++) {
            list.add(strings[i].charAt(n) + strings[i]);
        }
        
        Collections.sort(list);
        
        for(int i = 0; i < list.size(); i++) {
            answer[i] = list.get(i).substring(1);
        }
        
        return answer;
    }
}

팀 프로젝트 진행

뉴스 피드 프로젝트 Comment CRUD 구현

// CommentController

package com.sparta.wildcard_newsfeed.domain.comment.controller;

import com.sparta.wildcard_newsfeed.domain.comment.dto.CommentRequestDto;
import com.sparta.wildcard_newsfeed.domain.comment.dto.CommentResponseDto;
import com.sparta.wildcard_newsfeed.domain.comment.service.CommentService;
import com.sparta.wildcard_newsfeed.domain.common.CommonResponseDto;
import com.sparta.wildcard_newsfeed.security.AuthenticationUser;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/post/{postId}/comment")
public class CommentController {

    private final CommentService commentService;

    // 댓글 추가
    @PostMapping
    public ResponseEntity<CommonResponseDto<CommentResponseDto>> addComment(
            @AuthenticationPrincipal AuthenticationUser user,
            @PathVariable(name = "postId") long postId,
            @RequestBody CommentRequestDto commentRequestDto
    ) {
        CommentResponseDto commentResponseDto = commentService.addComment(postId, commentRequestDto, user);
        return ResponseEntity.ok()
                .body(CommonResponseDto.<CommentResponseDto>builder()
                        .statusCode(HttpStatus.OK.value())
                        .message("댓글 등록 성공")
                        .data(commentResponseDto)
                        .build());
    }

    @PatchMapping("{commentId}")
    public ResponseEntity<CommonResponseDto<CommentResponseDto>> updateComment(
            @AuthenticationPrincipal AuthenticationUser user,
            @Valid @RequestBody CommentRequestDto commentRequestDto,
            @PathVariable(name = "postId") Long postId,
            @PathVariable(name = "commentId") long commentId
    ) {
        CommentResponseDto commentResponseDto = commentService.updateComment(postId, commentId, commentRequestDto, user);
        return ResponseEntity.ok()
                .body(CommonResponseDto.<CommentResponseDto>builder()
                        .statusCode(HttpStatus.OK.value())
                        .message("댓글 수정 성공")
                        .data(commentResponseDto)
                        .build());
    }

    @DeleteMapping("{commentId}")
    public ResponseEntity<CommonResponseDto<CommentResponseDto>> deleteComment(
            @AuthenticationPrincipal AuthenticationUser user,
            @PathVariable(name = "postId") long postId,
            @PathVariable(name = "commentId") long commentId
    ) {
        commentService.deleteComment(postId, commentId, user.getUsername());
        return ResponseEntity.ok()
                .body(CommonResponseDto.<CommentResponseDto>builder()
                        .statusCode(HttpStatus.OK.value())
                        .message("댓글 삭제 성공")
                        .build());
    }
}




// CommentRequestDto

package com.sparta.wildcard_newsfeed.domain.comment.dto;

import jakarta.validation.constraints.NotBlank;
import lombok.Getter;

@Getter
public class CommentRequestDto {

    @NotBlank(message = "댓글 내용은 필수 입력 값입니다.")
    private String comment;

    public CommentRequestDto() {
        // 기본 생성자
    }

    public CommentRequestDto(String comment) {
        this.comment = comment;
    }
}



// CommentResponseDto

package com.sparta.wildcard_newsfeed.domain.comment.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.sparta.wildcard_newsfeed.domain.comment.entity.Comment;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class CommentResponseDto {
    private Long id;
    private String comment;
    private String username;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    private Long postId;

    public CommentResponseDto(Comment comment) {
        this.id = comment.getId();
        this.comment = comment.getContent();
        this.username = comment.getUser().getName();
        this.postId = comment.getPost().getId();
        this.createdAt = comment.getCreatedAt();
        this.updatedAt = comment.getUpdatedAt();
    }
}



// PostWithCommentsResponseDto

package com.sparta.wildcard_newsfeed.domain.comment.dto;

import com.sparta.wildcard_newsfeed.domain.post.dto.PostResponseDto;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
public class PostWithCommentsResponseDto {
    private PostResponseDto post;
    private List<CommentResponseDto> comments;

    public PostWithCommentsResponseDto(PostResponseDto post, List<CommentResponseDto> comments) {
        this.post = post;
        this.comments = comments;
    }

}



// Comment

package com.sparta.wildcard_newsfeed.domain.comment.entity;

import com.sparta.wildcard_newsfeed.domain.common.TimeStampEntity;
import com.sparta.wildcard_newsfeed.domain.post.entity.Post;
import com.sparta.wildcard_newsfeed.domain.user.entity.User;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Entity
@NoArgsConstructor
public class Comment extends TimeStampEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id", nullable = false)
    private Post post;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @Column(nullable = false)
    private String content;
    private Long likeCount;

    public Comment(String content, User user, Post post) {
        this.content = content;
        this.user = user;
        this.post = post;
    }


    public void update(String comment) {
        this.content = comment;
    }
}



// CommentRepository

package com.sparta.wildcard_newsfeed.domain.comment.repository;

import com.sparta.wildcard_newsfeed.domain.comment.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;


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



// CommentService

package com.sparta.wildcard_newsfeed.domain.comment.service;

import com.sparta.wildcard_newsfeed.domain.comment.dto.CommentRequestDto;
import com.sparta.wildcard_newsfeed.domain.comment.dto.CommentResponseDto;
import com.sparta.wildcard_newsfeed.domain.comment.entity.Comment;
import com.sparta.wildcard_newsfeed.domain.comment.repository.CommentRepository;
import com.sparta.wildcard_newsfeed.domain.post.entity.Post;
import com.sparta.wildcard_newsfeed.domain.post.repository.PostRepository;
import com.sparta.wildcard_newsfeed.domain.user.entity.User;
import com.sparta.wildcard_newsfeed.domain.user.repository.UserRepository;
import com.sparta.wildcard_newsfeed.security.AuthenticationUser;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class CommentService {

    private final PostRepository postRepository;
    private final CommentRepository commentRepository;
    private final UserRepository userRepository;

    @Transactional
    public CommentResponseDto addComment(long postId, CommentRequestDto request, AuthenticationUser user) {
        User byUsercode = userRepository.findByUsercode(user.getUsername())
                .orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다."));

        // DB에 게시물이 존재하지 않는 경우
        Post post = findPostById(postId);
        Comment comment = commentRepository.save(new Comment(request.getComment(), byUsercode, post));
        return new CommentResponseDto(comment);
    }

    public CommentResponseDto updateComment(long postId, long commentId, CommentRequestDto request, AuthenticationUser user) {
        // DB에 게시물이 존재하지 않는 경우
        findPostById(postId);
        // 해당 댓글이 DB에 존재하지 않는 경우
        Comment comment = findCommentById(commentId);

        // 작성자가 동일하지 않는 경우
        if (!Objects.equals(comment.getUser().getUsercode(), user.getUsername())) {
            throw new IllegalArgumentException("작성자만 수정할 수 있습니다.");
        }

        comment.update(request.getComment());
        commentRepository.save(comment);
        return new CommentResponseDto(comment);
    }

    public void deleteComment(long postId, long commentId, String username) {
        // DB에 게시물이 존재하지 않는 경우
        findPostById(postId);

        // 해당 댓글이 DB에 존재하지 않는 경우
        Comment comment = findCommentById(commentId);

        // 작성자가 동일하지 않는 경우
        if (!Objects.equals(comment.getUser().getUsercode(), username)) {
            throw new IllegalArgumentException("작성자만 삭제할 수 있습니다.");
        }

        commentRepository.delete(comment);
    }

    public List<CommentResponseDto> findAllCommentsByPostId(long postId) {
        // 해당 postId와 연관된 댓글을 조회하는 로직 구현
        List<Comment> comments = commentRepository.findByPostId(postId);
        return comments.stream()
                .map(CommentResponseDto::new)
                .collect(Collectors.toList());
    }

    public Comment findCommentById(Long commentId) {
        return commentRepository.findById(commentId)
                .orElseThrow(() -> new IllegalArgumentException("해당 댓글이 존재하지 않습니다."));
    }

    private Post findPostById(long id) {
        return postRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("해당 게시물이 존재하지 않습니다."));
    }

    public List<CommentResponseDto> findAll() {
        List<Comment> commentlist = commentRepository.findAll();
        return commentlist.stream()
                .sorted(Comparator.comparing(Comment::getCreatedAt).reversed())
                .map(CommentResponseDto::new)
                .toList();
    }
}



profile
야옹

0개의 댓글