-
Notifications
You must be signed in to change notification settings - Fork 13
Feat/week 1 #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 강지원
Are you sure you want to change the base?
Feat/week 1 #3
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,3 +35,5 @@ out/ | |
|
|
||
| ### VS Code ### | ||
| .vscode/ | ||
|
|
||
| .env | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| # backend-study-sns | ||
| 강지원 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package com.example.devSns.controller; | ||
|
|
||
| import com.example.devSns.entity.Comment; | ||
| import com.example.devSns.service.CommentService; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequestMapping("post/{postId}/comment") | ||
| public class CommentController { | ||
| private CommentService commentService; | ||
|
|
||
| public CommentController(CommentService commentService) { | ||
| this.commentService = commentService; | ||
| } | ||
|
|
||
| @GetMapping | ||
| public List<Comment> getComments(@PathVariable Long postId) { | ||
| return commentService.getCommentByPost(postId); | ||
| } | ||
|
|
||
| @PostMapping | ||
| public Comment createComment(@PathVariable Long postId, @RequestBody Comment comment) { | ||
| return commentService.addComment(postId, comment); | ||
| } | ||
|
|
||
| @DeleteMapping("/{commentId}") | ||
| public void deleteComment(@PathVariable Long commentId) { | ||
| commentService.deleteComment(commentId); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package com.example.devSns.controller; | ||
|
|
||
| import com.example.devSns.entity.Post; | ||
| import com.example.devSns.service.PostService; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/post") | ||
| public class PostController { | ||
| private final PostService postService; | ||
|
|
||
| public PostController(PostService postService) { | ||
| this.postService = postService; | ||
| } | ||
|
|
||
| @GetMapping | ||
| public List<Post> getAllPosts(){ | ||
| return postService.findAll(); | ||
| } | ||
|
|
||
| @GetMapping("/{id}") | ||
| public Post getPostById(@PathVariable Long id){ | ||
| return postService.findById(id).orElseThrow(()-> new RuntimeException("post not found")); | ||
| } | ||
|
|
||
| @PostMapping | ||
| public Post createPost(@RequestBody Post post){ | ||
| return postService.save(post); | ||
| } | ||
|
|
||
| @PutMapping("/{id}") | ||
| public Post updatePost(@PathVariable Long id, @RequestBody Post updatedPost){ | ||
|
|
||
| return postService.updatePost(id,updatedPost); | ||
| } | ||
|
|
||
| @DeleteMapping("/{id}") | ||
| public void deletePost(@PathVariable Long id){ | ||
| postService.delete(id); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package com.example.devSns.entity; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonBackReference; | ||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
| import java.time.LocalDateTime; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Setter | ||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| @Builder | ||
| public class Comment{ | ||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| private String content; | ||
| private String username; | ||
| private LocalDateTime createdAt; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| @JoinColumn(name="post_id") | ||
|
Comment on lines
+19
to
+24
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. entity에서 DB 스키마 관련 제약조건을 추가해서 더 안전하게 구성할 수 있습니다!
// 어노테이션 적용 예시
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(
name = "user_id",
nullable = false,
foreignKey = @ForeignKey(name = "fk_diary_user_id_ref_user_id")
)
private UserEntity user; |
||
| @JsonBackReference | ||
| private Post post; | ||
|
|
||
| @PrePersist | ||
| public void onCreate(){ | ||
| createdAt = LocalDateTime.now(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package com.example.devSns.entity; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonManagedReference; | ||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Setter | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Entity에서 Setter 사용은 지양하는 것이 좋습니다! 왜냐하면, setter를 사용한다는 것은 외부에서 entity 값을 마음대로 수정하도록 하는 것인데, 이는 캡슐화 관점에서 좋지 않습니다. 객체의 값을 직접 수정하지 않고 객체에 수정 작업을 시킨다는 관점으로 코드를 작성하면 더 객체 지향적인 코드가 됩니다! entity에서 setter를 사용하지 않도록 습관 들이면 좋습니다! |
||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| @Builder | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Builder 패턴의 경우 호불호가 갈리는 편입니다. Builder를 쓰면 선택적으로 필드를 구성할 수 있다는 장점이 있지만, 컴파일 때 필수 필드에 모두 유효한 값이 들어갔는지 체크하기 어렵다는 단점도 있습니다. 이 점 고려하셔서 사용하시면 될 것 같습니다! |
||
| public class Post { | ||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| private String content; | ||
| private int likes; | ||
| private String username; | ||
| private LocalDateTime createdAt; | ||
| private LocalDateTime updatedAt; | ||
|
|
||
| @OneToMany(mappedBy = "post", cascade = CascadeType.ALL,orphanRemoval = true) | ||
| @JsonManagedReference | ||
| private List<Comment> comments = new ArrayList<>(); | ||
|
Comment on lines
+28
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 양방향 연관관계를 사용해주셨는데, 양방향 연관관계와 단방향 연관관계의 장단점이 무엇일까요? |
||
| @PrePersist | ||
| public void onCreate(){ | ||
| createdAt = LocalDateTime.now(); | ||
| updatedAt = LocalDateTime.now(); | ||
| } | ||
|
|
||
| @PreUpdate | ||
| public void onUpdate(){ | ||
| updatedAt = LocalDateTime.now(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.example.devSns.repository; | ||
|
|
||
| import com.example.devSns.entity.Comment; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import java.util.List; | ||
|
|
||
| public interface CommentRepository extends JpaRepository<Comment, Long> { | ||
| List<Comment> findByPost_Id(Long postId); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package com.example.devSns.repository; | ||
|
|
||
| import com.example.devSns.entity.Post; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface PostRepository extends JpaRepository<Post, Long> {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package com.example.devSns.service; | ||
|
|
||
| import com.example.devSns.entity.Comment; | ||
| import com.example.devSns.entity.Post; | ||
| import com.example.devSns.repository.CommentRepository; | ||
| import com.example.devSns.repository.PostRepository; | ||
| import org.springframework.stereotype.Service; | ||
| import java.util.List; | ||
|
|
||
| @Service | ||
| public class CommentService { | ||
| private final CommentRepository commentRepository; | ||
| private final PostRepository postRepository; | ||
|
|
||
| public CommentService(CommentRepository commentRepository, PostRepository postRepository) { | ||
| this.commentRepository = commentRepository; | ||
| this.postRepository = postRepository; | ||
| } | ||
|
|
||
| public List<Comment> getCommentByPost(Long postId){ | ||
| return commentRepository.findByPost_Id(postId); | ||
|
Comment on lines
+10
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 |
||
| } | ||
|
|
||
| public Comment addComment(Long postId, Comment comment){ | ||
| Post post = postRepository.findById(postId).orElseThrow(()-> new IllegalArgumentException("게시글 없음")); | ||
| comment.setPost(post); | ||
| return commentRepository.save(comment); | ||
| } | ||
|
|
||
| public void deleteComment(Long id){ | ||
| commentRepository.deleteById(id); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package com.example.devSns.service; | ||
|
|
||
| import com.example.devSns.entity.Post; | ||
| import com.example.devSns.repository.PostRepository; | ||
| import org.springframework.stereotype.Service; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.util.List; | ||
| import java.util.Optional; | ||
|
|
||
| @Service | ||
| public class PostService { | ||
| private final PostRepository postRepository; | ||
|
|
||
| public PostService(PostRepository postRepository) { | ||
| this.postRepository = postRepository; | ||
| } | ||
|
|
||
| public List<Post> findAll(){ | ||
| return postRepository.findAll(); | ||
| } | ||
|
|
||
| public Optional<Post> findById(Long id){ | ||
| return postRepository.findById(id); | ||
| } | ||
|
Comment on lines
+23
to
+25
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. findById에 대한 null 체크를 service 계층에서 미리 수행하고 postService.findById()의 반환 타입을 Post로 수정하면 Controller에서의 Optional 에러 체크 로직을 service 계층으로 옮길 수 있을 것 같습니다! 이렇게 구성하면 controller에서는 db로부터 조회한 객체의 optional 체크를 신경쓰지 않고 단순히 사용자 요청 응답에만 집중할 수 있습니다. |
||
|
|
||
| public Post save(Post post){ | ||
| return postRepository.save(post); | ||
| } | ||
| public Post updatePost(Long id, Post updatedPost) { | ||
| Post existingPost = postRepository.findById(id).orElseThrow(() -> new RuntimeException("Post not found")); | ||
|
|
||
| updatedPost.setCreatedAt(existingPost.getCreatedAt()); | ||
| updatedPost.setUpdatedAt(LocalDateTime.now()); | ||
|
Comment on lines
+33
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. createdAt은 수정 시 갱신하지 않는 것이 적절해 보입니다! 그리고 현재 |
||
|
|
||
| updatedPost.setId(id); | ||
|
|
||
| return postRepository.save(updatedPost); | ||
| } | ||
|
|
||
| public void delete(Long id){ | ||
| postRepository.deleteById(id); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,13 @@ | ||
| spring.application.name=devSns | ||
|
|
||
| # DB ???? | ||
| spring.datasource.url=${DATASOURCE_URL} | ||
| spring.datasource.username=${DATASOURCE_USERNAME} | ||
| spring.datasource.password=${DATASOURCE_PASSWORD} | ||
| # DB ???? | ||
| spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver | ||
|
|
||
| spring.jpa.hibernate.ddl-auto=update | ||
| # true? ???? ?? ???? sql?? ???? ??? ? ????. | ||
| spring.jpa.show-sql=true | ||
| spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment까지 작성해 주셨네요! 좋습니다