Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
package com.example.springhw32.controller;

import com.example.springhw32.dto.CommentDto;
import com.example.springhw32.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/posts")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RequestMapping("/posts/comments")

이렇게 써도 될 듯
(댓글을 한 개라도 더 달려는 노력..)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 엔드포인트 그냥 받아적다 보니 똑같다는걸 인지를 못했네..

public class CommentController {

private final CommentService commentService;

// 댓글 작성
@PostMapping("/comments")
public CommentDto addComment(@ModelAttribute CommentDto commentDto, @RequestParam Long postId) {
return commentService.addComment(commentDto, postId);
}

// 특정 게시물에 달린 모든 댓글 조회
@GetMapping("/comments/{postId}")
public List<CommentDto> getAllComments(@PathVariable Long postId) {
return commentService.getAllComments(postId);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
package com.example.springhw32.controller;

import com.example.springhw32.dto.PostDto;
import com.example.springhw32.service.PostService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/posts")
public class PostController {

private final PostService postService;

// 글 등록
@PostMapping
public PostDto createPost(@ModelAttribute PostDto postDto, Long userId) {
return postService.createPost(postDto, userId);
}

// 최신순으로 글 조회
@GetMapping
public List<PostDto> findAllPostsByOrderByPostedAtDesc() {
return postService.findAllPostsByOrderByPostedAtDesc();
}

// 작성자 글 조회
@GetMapping("/{writer}")
public List<PostDto> findAllPostsByWriter(@PathVariable("writer") Long userId) {
return postService.findAllPostsByUserId(userId);
}

// 댓글 많은 순으로 글 조회
@GetMapping("/comments")
public List<PostDto> findAllPostsByOrderByCommentCountDesc() {
return postService.findAllPostsByOrderByCommentCountDesc();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
package com.example.springhw32.controller;

import com.example.springhw32.dto.UserDto;
import com.example.springhw32.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class UserController {

private final UserService userService;

// 회원 가입
@PostMapping("/users")
public UserDto join(@ModelAttribute UserDto userDto) {
return userService.join(userDto);
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/example/springhw32/dto/CommentDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.example.springhw32.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class CommentDto {

private String comment;

}
13 changes: 13 additions & 0 deletions src/main/java/com/example/springhw32/dto/PostDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
package com.example.springhw32.dto;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

@Getter
@Setter
public class PostDto {

private String title;

private String content;

private int commentCount;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createdAt은 Dto에 왜 안 넣었어?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dto에 넣으니까 파라미터로 입력을 받지 않아서 null로 반환하길래 빼긴 했는데
엔티티에서 Dto로 변환할때 setPostedAt을 하는 방법도 있었군,,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아주 좋아용~~ 이거에 대해서는 오늘 알려줄게용~~

}
9 changes: 9 additions & 0 deletions src/main/java/com/example/springhw32/dto/UserDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package com.example.springhw32.dto;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class UserDto {

private String username;

private String password;

}
17 changes: 17 additions & 0 deletions src/main/java/com/example/springhw32/entity/Comment.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
package com.example.springhw32.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class Comment {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;

@ManyToOne
private Post post;

@Column(nullable = false)
private String comment;

}
26 changes: 26 additions & 0 deletions src/main/java/com/example/springhw32/entity/Post.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
package com.example.springhw32.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

@Entity
@Getter
@Setter
public class Post {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@ManyToOne
private User user;

@Column(nullable = false)
private String title;

@Column(nullable = false)
private String content;

private int commentCount;

private LocalDateTime postedAt;

}
17 changes: 17 additions & 0 deletions src/main/java/com/example/springhw32/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
package com.example.springhw32.entity;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Entity
@Getter
@Setter
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(nullable = false)
private String username;

@Column(nullable = false)
private String password;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.example.springhw32.repository;

public interface CommentRepository {
import com.example.springhw32.dto.CommentDto;
import com.example.springhw32.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface CommentRepository extends JpaRepository<Comment, Long> {

List<Comment> findAllByPostId(Long postId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package com.example.springhw32.repository;

public interface PostRepository {
import com.example.springhw32.dto.PostDto;
import com.example.springhw32.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PostRepository extends JpaRepository<Post, Long> {

List<Post> findAllByOrderByPostedAtDesc();

List<Post> findAllByUserId(Long userId);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 나는 Jpa가 이렇게 똑똑한 줄 몰랐네

JPA에서는 경로를 명확히 지정하는 게 안전하지만, 지금처럼 연관 관계가 명확하게 설정되어 있다면 findAllByUsername처럼 짧은 메서드명으로도 작동할 수 있다. 하지만 현재 돌아가고 있으면 괜찮지만, 다른 팀원이나 미래의 개발자가 코드를 이해하기 쉽게 명시적으로 작성하는 것이 권장된다.

나는 findAllByUse_Username으로 쿼리 날리려고 메서드명 작성했는데 찾아보니까 연관 관계가 매핑되어 있으면 줄여써도 가능하구낭


List<Post> findAllByOrderByCommentCountDesc();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.example.springhw32.repository;

public interface UserRepository {
import com.example.springhw32.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

}
46 changes: 46 additions & 0 deletions src/main/java/com/example/springhw32/service/CommentService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
package com.example.springhw32.service;

import com.example.springhw32.dto.CommentDto;
import com.example.springhw32.dto.PostDto;
import com.example.springhw32.entity.Comment;
import com.example.springhw32.entity.Post;
import com.example.springhw32.repository.CommentRepository;
import com.example.springhw32.repository.PostRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CommentService {

private final CommentRepository commentRepository;
private final PostRepository postRepository;

// 댓글 작성
public CommentDto addComment(CommentDto commentDto, Long postId) {
Post post = postRepository.findById(postId).orElseThrow(NullPointerException::new);

Comment comment = new Comment();
comment.setComment(commentDto.getComment());
comment.setPost(post);
commentRepository.save(comment);

post.setCommentCount(post.getCommentCount() + 1);
postRepository.save(post);

return commentDto;
}

// 특정 게시글에 작성된 댓글 조회
public List<CommentDto> getAllComments(Long postId) {
return commentRepository.findAllByPostId(postId).stream()
.map(this::convertToDto)
.collect(Collectors.toList());
}

// Entity -> Dto
private CommentDto convertToDto(Comment comment) {
CommentDto commentDto = new CommentDto();
commentDto.setComment(comment.getComment());
return commentDto;
}
}
61 changes: 61 additions & 0 deletions src/main/java/com/example/springhw32/service/PostService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,66 @@
package com.example.springhw32.service;

import com.example.springhw32.dto.PostDto;
import com.example.springhw32.entity.Post;
import com.example.springhw32.entity.User;
import com.example.springhw32.repository.PostRepository;
import com.example.springhw32.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class PostService {

private final PostRepository postRepository;
private final UserRepository userRepository;

// 글 작성
public PostDto createPost(PostDto postDto, Long userId) {
User user = userRepository.findById(userId).orElseThrow(NullPointerException::new);

Post post = new Post();
post.setTitle(postDto.getTitle());
post.setContent(postDto.getContent());
post.setCommentCount(0);
post.setPostedAt(LocalDateTime.now());
post.setUser(user);
postRepository.save(post);

return postDto;
}

// 최신순으로 글 조회
public List<PostDto> findAllPostsByOrderByPostedAtDesc() {
return postRepository.findAllByOrderByPostedAtDesc().stream()
.map(this::convertToDto)
.collect(Collectors.toList());
}

// 특정 회원이 작성한 글 조회
public List<PostDto> findAllPostsByUserId(Long userId) {
return postRepository.findAllByUserId(userId).stream()
.map(this::convertToDto)
.collect(Collectors.toList());
}

// 댓글 많은 순으로 정렬 조회
public List<PostDto> findAllPostsByOrderByCommentCountDesc() {
return postRepository.findAllByOrderByCommentCountDesc().stream()
.map(this::convertToDto)
.collect(Collectors.toList());
}

// Entity -> Dto
private PostDto convertToDto(Post post) {
PostDto postDto = new PostDto();
postDto.setTitle(post.getTitle());
postDto.setContent(post.getContent());
postDto.setCommentCount(post.getCommentCount());
return postDto;
}
}
Loading