From 988e6a7af7fdb11984e203d27a6f7a337ba75bb5 Mon Sep 17 00:00:00 2001 From: woowal Date: Sun, 31 Dec 2023 17:20:20 +0900 Subject: [PATCH 1/3] feat: member --- .../comment/controller/CommentController.java | 32 +++++++++++++ .../example/jpa/comment/domain/Comment.java | 30 ++++++++++++ .../dto/request/CommentCreateRequest.java | 16 +++++++ .../comment/dto/response/CommentResponse.java | 20 ++++++++ .../jpa/comment/service/CommentService.java | 31 +++++++++++++ .../member/controller/MemberController.java | 34 +++++++++++--- .../com/example/jpa/member/domain/Member.java | 2 +- .../dto/request/MemberUpdateRequest.java | 16 +++++++ .../jpa/member/service/MemberService.java | 24 ++++++++++ .../jpa/post/controller/PostController.java | 44 ++++++++++++++++++ .../com/example/jpa/post/domain/Post.java | 37 +++++++++++++++ .../post/dto/request/PostCreateRequest.java | 21 +++++++++ .../post/dto/request/PostUpdateRequest.java | 18 ++++++++ .../jpa/post/dto/response/PostResponse.java | 23 ++++++++++ .../example/jpa/post/service/PostService.java | 46 +++++++++++++++++++ .../jpa/repository/CommentRepository.java | 7 +++ .../jpa/repository/PostRepository.java | 7 +++ src/main/resources/application.yml | 2 +- 18 files changed, 402 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/example/jpa/comment/controller/CommentController.java create mode 100644 src/main/java/com/example/jpa/comment/domain/Comment.java create mode 100644 src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java create mode 100644 src/main/java/com/example/jpa/comment/dto/response/CommentResponse.java create mode 100644 src/main/java/com/example/jpa/comment/service/CommentService.java create mode 100644 src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java create mode 100644 src/main/java/com/example/jpa/post/controller/PostController.java create mode 100644 src/main/java/com/example/jpa/post/domain/Post.java create mode 100644 src/main/java/com/example/jpa/post/dto/request/PostCreateRequest.java create mode 100644 src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java create mode 100644 src/main/java/com/example/jpa/post/dto/response/PostResponse.java create mode 100644 src/main/java/com/example/jpa/post/service/PostService.java create mode 100644 src/main/java/com/example/jpa/repository/CommentRepository.java create mode 100644 src/main/java/com/example/jpa/repository/PostRepository.java diff --git a/src/main/java/com/example/jpa/comment/controller/CommentController.java b/src/main/java/com/example/jpa/comment/controller/CommentController.java new file mode 100644 index 0000000..fed77de --- /dev/null +++ b/src/main/java/com/example/jpa/comment/controller/CommentController.java @@ -0,0 +1,32 @@ +package com.example.jpa.comment.controller; + +import com.example.jpa.comment.dto.request.CommentCreateRequest; +import com.example.jpa.comment.dto.response.CommentResponse; +import com.example.jpa.comment.service.CommentService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("api/comments") +@RequiredArgsConstructor +public class CommentController { + + private final CommentService commentService; + + @PostMapping + public ResponseEntity create(@RequestBody CommentCreateRequest commentCreateRequest) { + + commentService.create(commentCreateRequest); + + return ResponseEntity.ok().build(); + } + + @GetMapping("/{id}") + public ResponseEntity findOne(@PathVariable("id") Long id) { + + CommentResponse commentResponse = commentService.findOne(id); + + return ResponseEntity.ok(commentResponse); + } +} diff --git a/src/main/java/com/example/jpa/comment/domain/Comment.java b/src/main/java/com/example/jpa/comment/domain/Comment.java new file mode 100644 index 0000000..9718606 --- /dev/null +++ b/src/main/java/com/example/jpa/comment/domain/Comment.java @@ -0,0 +1,30 @@ +package com.example.jpa.comment.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Comment { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String content; + + @Builder + public Comment(String content) { + this.content = content; + } + + void update(String content) { + this.content = content; + } +} diff --git a/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java b/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java new file mode 100644 index 0000000..a5389c9 --- /dev/null +++ b/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java @@ -0,0 +1,16 @@ +package com.example.jpa.comment.dto.request; + +import com.example.jpa.comment.domain.Comment; +import lombok.Getter; + +@Getter +public class CommentCreateRequest { + + private String content; + + public Comment toEntity() { + return Comment.builder() + .content(this.content) + .build(); + } +} diff --git a/src/main/java/com/example/jpa/comment/dto/response/CommentResponse.java b/src/main/java/com/example/jpa/comment/dto/response/CommentResponse.java new file mode 100644 index 0000000..ef415d0 --- /dev/null +++ b/src/main/java/com/example/jpa/comment/dto/response/CommentResponse.java @@ -0,0 +1,20 @@ +package com.example.jpa.comment.dto.response; + +import com.example.jpa.comment.domain.Comment; +import lombok.Getter; + +@Getter +public class CommentResponse { + + private Long id; + private String content; + + public CommentResponse(Long id, String content) { + this.id = id; + this.content = content; + } + + public static CommentResponse from(Comment comment) { + return new CommentResponse(comment.getId(), comment.getContent()); + } +} diff --git a/src/main/java/com/example/jpa/comment/service/CommentService.java b/src/main/java/com/example/jpa/comment/service/CommentService.java new file mode 100644 index 0000000..459a9ba --- /dev/null +++ b/src/main/java/com/example/jpa/comment/service/CommentService.java @@ -0,0 +1,31 @@ +package com.example.jpa.comment.service; + +import com.example.jpa.comment.domain.Comment; +import com.example.jpa.comment.dto.request.CommentCreateRequest; +import com.example.jpa.comment.dto.response.CommentResponse; +import com.example.jpa.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.NoSuchElementException; + +@Service +@RequiredArgsConstructor +public class CommentService { + + private final CommentRepository commentRepository; + + @Transactional + public void create(CommentCreateRequest commentCreateRequest) { + commentRepository.save(commentCreateRequest.toEntity()); + } + + @Transactional(readOnly = true) + public CommentResponse findOne(Long id) { + Comment comment = commentRepository.findById(id) + .orElseThrow(() -> new NoSuchElementException("멤버가 존재하지 않습니다.")); + + return CommentResponse.from(comment); + } +} diff --git a/src/main/java/com/example/jpa/member/controller/MemberController.java b/src/main/java/com/example/jpa/member/controller/MemberController.java index 16fb71f..a27c4c3 100644 --- a/src/main/java/com/example/jpa/member/controller/MemberController.java +++ b/src/main/java/com/example/jpa/member/controller/MemberController.java @@ -1,17 +1,15 @@ package com.example.jpa.member.controller; import com.example.jpa.member.dto.request.MemberCreateRequest; +import com.example.jpa.member.dto.request.MemberUpdateRequest; import com.example.jpa.member.dto.response.MemberResponse; import com.example.jpa.member.service.MemberService; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @RequestMapping("api/members") @@ -35,4 +33,28 @@ public ResponseEntity findOne(@PathVariable("id") Long id) { return ResponseEntity.ok(memberResponse); } + + @PatchMapping("/{id}") + public ResponseEntity update(@PathVariable("id") Long id, @RequestBody MemberUpdateRequest memberUpdateRequest) { + + memberService.update(id, memberUpdateRequest); + + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/{id}") + public ResponseEntity delete(@PathVariable("id") Long id) { + + memberService.delete(id); + + return ResponseEntity.ok().build(); + } + + @GetMapping + public ResponseEntity findAll() { + + List memberResponses = memberService.findAll(); + + return ResponseEntity.ok(memberResponses); + } } diff --git a/src/main/java/com/example/jpa/member/domain/Member.java b/src/main/java/com/example/jpa/member/domain/Member.java index 92ca27b..07edd67 100644 --- a/src/main/java/com/example/jpa/member/domain/Member.java +++ b/src/main/java/com/example/jpa/member/domain/Member.java @@ -25,7 +25,7 @@ public Member(String name) { this.name = name; } - void update(String name) { + public void update(String name) { this.name = name; } } diff --git a/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java b/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java new file mode 100644 index 0000000..37cf0e4 --- /dev/null +++ b/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java @@ -0,0 +1,16 @@ +package com.example.jpa.member.dto.request; + +import com.example.jpa.member.domain.Member; +import lombok.Getter; + +@Getter +public class MemberUpdateRequest { + + private String name; + + public Member toEntity() { + return Member.builder() + .name(this.name) + .build(); + } +} diff --git a/src/main/java/com/example/jpa/member/service/MemberService.java b/src/main/java/com/example/jpa/member/service/MemberService.java index fa8740b..27fae85 100644 --- a/src/main/java/com/example/jpa/member/service/MemberService.java +++ b/src/main/java/com/example/jpa/member/service/MemberService.java @@ -2,10 +2,17 @@ import com.example.jpa.member.domain.Member; import com.example.jpa.member.dto.request.MemberCreateRequest; +import com.example.jpa.member.dto.request.MemberUpdateRequest; import com.example.jpa.member.dto.response.MemberResponse; +import com.example.jpa.post.domain.Post; +import com.example.jpa.post.dto.request.PostUpdateRequest; import com.example.jpa.repository.MemberRepository; + +import java.util.List; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.stream.Collectors; + import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,5 +36,22 @@ public MemberResponse findOne(Long id) { return MemberResponse.from(member); } + @Transactional + public void update(Long id, MemberUpdateRequest memberUpdateRequest) { + Member member = memberRepository.findById(id) + .orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다.")); + member.update(memberUpdateRequest.getName()); + } + + @Transactional + public void delete(Long id) { + memberRepository.deleteById(id); + } + @Transactional(readOnly = true) + public List findAll() { + return memberRepository.findAll().stream() + .map(MemberResponse::from) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/com/example/jpa/post/controller/PostController.java b/src/main/java/com/example/jpa/post/controller/PostController.java new file mode 100644 index 0000000..55f4215 --- /dev/null +++ b/src/main/java/com/example/jpa/post/controller/PostController.java @@ -0,0 +1,44 @@ +package com.example.jpa.post.controller; + +import com.example.jpa.comment.dto.request.CommentCreateRequest; +import com.example.jpa.comment.dto.response.CommentResponse; +import com.example.jpa.comment.service.CommentService; +import com.example.jpa.post.dto.request.PostCreateRequest; +import com.example.jpa.post.dto.request.PostUpdateRequest; +import com.example.jpa.post.dto.response.PostResponse; +import com.example.jpa.post.service.PostService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("api/posts") +@RequiredArgsConstructor +public class PostController { + + private final PostService postService; + + @PostMapping + public ResponseEntity create(@RequestBody PostCreateRequest postCreateRequest) { + + postService.create(postCreateRequest); + + return ResponseEntity.ok().build(); + } + + @GetMapping("/{id}") + public ResponseEntity findOne(@PathVariable("id") Long id) { + + PostResponse postResponse = postService.findOne(id); + + return ResponseEntity.ok(postResponse); + } + + @PatchMapping("/{id}") + public ResponseEntity update(@PathVariable("id") Long id, @RequestBody PostUpdateRequest postUpdateRequest) { + + postService.update(id, postUpdateRequest); + + return ResponseEntity.ok().build(); + } +} diff --git a/src/main/java/com/example/jpa/post/domain/Post.java b/src/main/java/com/example/jpa/post/domain/Post.java new file mode 100644 index 0000000..47f1ed2 --- /dev/null +++ b/src/main/java/com/example/jpa/post/domain/Post.java @@ -0,0 +1,37 @@ +package com.example.jpa.post.domain; + +import com.example.jpa.member.domain.Member; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Post { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "member") + private Member member; + + private String title; + private String content; + + @Builder + public Post(Member member, String title, String content) { + this.member = member; + this.title = title; + this.content = content; + } + + public void update(String title, String content) { + this.title = title; + this.content = content; + } +} diff --git a/src/main/java/com/example/jpa/post/dto/request/PostCreateRequest.java b/src/main/java/com/example/jpa/post/dto/request/PostCreateRequest.java new file mode 100644 index 0000000..6501bb3 --- /dev/null +++ b/src/main/java/com/example/jpa/post/dto/request/PostCreateRequest.java @@ -0,0 +1,21 @@ +package com.example.jpa.post.dto.request; + +import com.example.jpa.member.domain.Member; +import com.example.jpa.post.domain.Post; +import lombok.Getter; + +@Getter +public class PostCreateRequest { + + private Long member; + private String title; + private String content; + + public Post toEntity(Member member) { + return Post.builder() + .member(member) + .title(this.title) + .content(this.content) + .build(); + } +} diff --git a/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java b/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java new file mode 100644 index 0000000..8d23345 --- /dev/null +++ b/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java @@ -0,0 +1,18 @@ +package com.example.jpa.post.dto.request; + +import com.example.jpa.post.domain.Post; +import lombok.Getter; + +@Getter +public class PostUpdateRequest { + + private String title; + private String content; + + public Post toEntity() { + return Post.builder() + .title(this.title) + .content(this.content) + .build(); + } +} diff --git a/src/main/java/com/example/jpa/post/dto/response/PostResponse.java b/src/main/java/com/example/jpa/post/dto/response/PostResponse.java new file mode 100644 index 0000000..481fc2f --- /dev/null +++ b/src/main/java/com/example/jpa/post/dto/response/PostResponse.java @@ -0,0 +1,23 @@ +package com.example.jpa.post.dto.response; + +import com.example.jpa.member.domain.Member; +import com.example.jpa.post.domain.Post; +import lombok.Getter; + +@Getter +public class PostResponse { + + private Long id; + private String title; + private String content; + + public PostResponse(Long id, String title, String content) { + this.id = id; + this.title = title; + this.content = content; + } + + public static PostResponse from(Post post) { + return new PostResponse(post.getId(), post.getTitle(), post.getContent()); + } +} diff --git a/src/main/java/com/example/jpa/post/service/PostService.java b/src/main/java/com/example/jpa/post/service/PostService.java new file mode 100644 index 0000000..92d701a --- /dev/null +++ b/src/main/java/com/example/jpa/post/service/PostService.java @@ -0,0 +1,46 @@ +package com.example.jpa.post.service; + +import com.example.jpa.comment.domain.Comment; +import com.example.jpa.comment.dto.request.CommentCreateRequest; +import com.example.jpa.comment.dto.response.CommentResponse; +import com.example.jpa.member.domain.Member; +import com.example.jpa.post.domain.Post; +import com.example.jpa.post.dto.request.PostCreateRequest; +import com.example.jpa.post.dto.request.PostUpdateRequest; +import com.example.jpa.post.dto.response.PostResponse; +import com.example.jpa.repository.MemberRepository; +import com.example.jpa.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.NoSuchElementException; + +@Service +@RequiredArgsConstructor +public class PostService { + + private final PostRepository postRepository; + private final MemberRepository memberRepository; + + @Transactional + public void create(PostCreateRequest postCreateRequest) { + Member member = memberRepository.findById(postCreateRequest.getMember()).get(); + postRepository.save(postCreateRequest.toEntity(member)); + } + + @Transactional(readOnly = true) + public PostResponse findOne(Long id) { + Post post = postRepository.findById(id) + .orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다.")); + + return PostResponse.from(post); + } + + @Transactional + public void update(Long id, PostUpdateRequest postUpdateRequest) { + Post post = postRepository.findById(id) + .orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다.")); + post.update(postUpdateRequest.getTitle(), postUpdateRequest.getContent()); + } +} diff --git a/src/main/java/com/example/jpa/repository/CommentRepository.java b/src/main/java/com/example/jpa/repository/CommentRepository.java new file mode 100644 index 0000000..152de0e --- /dev/null +++ b/src/main/java/com/example/jpa/repository/CommentRepository.java @@ -0,0 +1,7 @@ +package com.example.jpa.repository; + +import com.example.jpa.comment.domain.Comment; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CommentRepository extends JpaRepository { +} diff --git a/src/main/java/com/example/jpa/repository/PostRepository.java b/src/main/java/com/example/jpa/repository/PostRepository.java new file mode 100644 index 0000000..0a9f831 --- /dev/null +++ b/src/main/java/com/example/jpa/repository/PostRepository.java @@ -0,0 +1,7 @@ +package com.example.jpa.repository; + +import com.example.jpa.post.domain.Post; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository { +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f13d82c..7391553 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,7 +3,7 @@ server: spring: datasource: - url: jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC + url: jdbc:mysql://localhost:3307/jpa?serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver username: root password: mysql From f9f9116c8b8add52a872a16a5877234fbd56099f Mon Sep 17 00:00:00 2001 From: woowal Date: Sun, 31 Dec 2023 18:22:19 +0900 Subject: [PATCH 2/3] feat: post --- .../example/jpa/comment/domain/Comment.java | 15 +++++++++---- .../com/example/jpa/member/domain/Member.java | 16 ++++++++++---- .../jpa/post/controller/PostController.java | 21 ++++++++++++++++--- .../com/example/jpa/post/domain/Post.java | 7 +++++++ .../jpa/post/dto/response/PostResponse.java | 17 +++++++++++++++ .../example/jpa/post/service/PostService.java | 21 ++++++++++++++++--- 6 files changed, 83 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/example/jpa/comment/domain/Comment.java b/src/main/java/com/example/jpa/comment/domain/Comment.java index 9718606..c0661ae 100644 --- a/src/main/java/com/example/jpa/comment/domain/Comment.java +++ b/src/main/java/com/example/jpa/comment/domain/Comment.java @@ -1,9 +1,8 @@ package com.example.jpa.comment.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import com.example.jpa.member.domain.Member; +import com.example.jpa.post.domain.Post; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -17,6 +16,14 @@ public class Comment { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @ManyToOne + @JoinColumn(name = "member") + private Member member; + + @ManyToOne + @JoinColumn(name = "post") + private Post post; + private String content; @Builder diff --git a/src/main/java/com/example/jpa/member/domain/Member.java b/src/main/java/com/example/jpa/member/domain/Member.java index 07edd67..978a7d7 100644 --- a/src/main/java/com/example/jpa/member/domain/Member.java +++ b/src/main/java/com/example/jpa/member/domain/Member.java @@ -1,14 +1,16 @@ package com.example.jpa.member.domain; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import com.example.jpa.comment.domain.Comment; +import com.example.jpa.post.domain.Post; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.List; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -20,6 +22,12 @@ public class Member { private String name; + @OneToMany(mappedBy = "member", orphanRemoval = true) + private List posts = new ArrayList<>(); + + @OneToMany(mappedBy = "member", orphanRemoval = true) + private List comments = new ArrayList<>(); + @Builder public Member(String name) { this.name = name; diff --git a/src/main/java/com/example/jpa/post/controller/PostController.java b/src/main/java/com/example/jpa/post/controller/PostController.java index 55f4215..c8dfddf 100644 --- a/src/main/java/com/example/jpa/post/controller/PostController.java +++ b/src/main/java/com/example/jpa/post/controller/PostController.java @@ -1,8 +1,5 @@ package com.example.jpa.post.controller; -import com.example.jpa.comment.dto.request.CommentCreateRequest; -import com.example.jpa.comment.dto.response.CommentResponse; -import com.example.jpa.comment.service.CommentService; import com.example.jpa.post.dto.request.PostCreateRequest; import com.example.jpa.post.dto.request.PostUpdateRequest; import com.example.jpa.post.dto.response.PostResponse; @@ -11,6 +8,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequestMapping("api/posts") @RequiredArgsConstructor @@ -41,4 +40,20 @@ public ResponseEntity update(@PathVariable("id") Long id, @Request return ResponseEntity.ok().build(); } + + @DeleteMapping("/{id}") + public ResponseEntity delete(@PathVariable("id") Long id) { + + postService.delete(id); + + return ResponseEntity.ok().build(); + } + + @GetMapping + public ResponseEntity findAll() { + + List postResponses = postService.findAll(); + + return ResponseEntity.ok(postResponses); + } } diff --git a/src/main/java/com/example/jpa/post/domain/Post.java b/src/main/java/com/example/jpa/post/domain/Post.java index 47f1ed2..f0ec41e 100644 --- a/src/main/java/com/example/jpa/post/domain/Post.java +++ b/src/main/java/com/example/jpa/post/domain/Post.java @@ -1,5 +1,6 @@ package com.example.jpa.post.domain; +import com.example.jpa.comment.domain.Comment; import com.example.jpa.member.domain.Member; import jakarta.persistence.*; import lombok.AccessLevel; @@ -7,6 +8,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.List; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -23,6 +27,9 @@ public class Post { private String title; private String content; + @OneToMany(mappedBy = "post", orphanRemoval = true) + private List comments = new ArrayList<>(); + @Builder public Post(Member member, String title, String content) { this.member = member; diff --git a/src/main/java/com/example/jpa/post/dto/response/PostResponse.java b/src/main/java/com/example/jpa/post/dto/response/PostResponse.java index 481fc2f..5dadefd 100644 --- a/src/main/java/com/example/jpa/post/dto/response/PostResponse.java +++ b/src/main/java/com/example/jpa/post/dto/response/PostResponse.java @@ -1,15 +1,28 @@ package com.example.jpa.post.dto.response; +import com.example.jpa.comment.domain.Comment; import com.example.jpa.member.domain.Member; import com.example.jpa.post.domain.Post; import lombok.Getter; +import java.util.List; + @Getter public class PostResponse { private Long id; private String title; + private String name; private String content; + private List comments; + + public PostResponse(Long id, String title, String name, String content, List comments) { + this.id = id; + this.title = title; + this.name = name; + this.content = content; + this.comments = comments; + } public PostResponse(Long id, String title, String content) { this.id = id; @@ -17,6 +30,10 @@ public PostResponse(Long id, String title, String content) { this.content = content; } + public static PostResponse from(Post post, String name, List comments) { + return new PostResponse(post.getId(), post.getTitle(), name, post.getContent(), comments); + } + public static PostResponse from(Post post) { return new PostResponse(post.getId(), post.getTitle(), post.getContent()); } diff --git a/src/main/java/com/example/jpa/post/service/PostService.java b/src/main/java/com/example/jpa/post/service/PostService.java index 92d701a..2f74894 100644 --- a/src/main/java/com/example/jpa/post/service/PostService.java +++ b/src/main/java/com/example/jpa/post/service/PostService.java @@ -1,20 +1,21 @@ package com.example.jpa.post.service; import com.example.jpa.comment.domain.Comment; -import com.example.jpa.comment.dto.request.CommentCreateRequest; -import com.example.jpa.comment.dto.response.CommentResponse; import com.example.jpa.member.domain.Member; import com.example.jpa.post.domain.Post; import com.example.jpa.post.dto.request.PostCreateRequest; import com.example.jpa.post.dto.request.PostUpdateRequest; import com.example.jpa.post.dto.response.PostResponse; +import com.example.jpa.repository.CommentRepository; import com.example.jpa.repository.MemberRepository; import com.example.jpa.repository.PostRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.NoSuchElementException; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -22,6 +23,7 @@ public class PostService { private final PostRepository postRepository; private final MemberRepository memberRepository; + private final CommentRepository commentRepository; @Transactional public void create(PostCreateRequest postCreateRequest) { @@ -33,8 +35,9 @@ public void create(PostCreateRequest postCreateRequest) { public PostResponse findOne(Long id) { Post post = postRepository.findById(id) .orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다.")); + List comments = commentRepository.findAll().stream().toList(); - return PostResponse.from(post); + return PostResponse.from(post, post.getMember().getName(), comments); } @Transactional @@ -43,4 +46,16 @@ public void update(Long id, PostUpdateRequest postUpdateRequest) { .orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다.")); post.update(postUpdateRequest.getTitle(), postUpdateRequest.getContent()); } + + @Transactional + public void delete(Long id) { + postRepository.deleteById(id); + } + + @Transactional(readOnly = true) + public List findAll() { + return postRepository.findAll().stream() + .map(PostResponse::from) + .collect(Collectors.toList()); + } } From f27e20f10ca920080f8982c21c98d99f56c2a4ab Mon Sep 17 00:00:00 2001 From: woowal Date: Mon, 1 Jan 2024 21:58:05 +0900 Subject: [PATCH 3/3] feat: comment --- .../comment/controller/CommentController.java | 27 +++++++++++++++ .../example/jpa/comment/domain/Comment.java | 11 ++++-- .../dto/request/CommentCreateRequest.java | 8 ++++- .../dto/request/CommentUpdateRequest.java | 10 ++++++ .../jpa/comment/service/CommentService.java | 34 +++++++++++++++++-- .../com/example/jpa/member/domain/Member.java | 4 +-- .../dto/request/MemberUpdateRequest.java | 6 ---- .../jpa/member/service/MemberService.java | 3 -- .../jpa/post/controller/PostController.java | 7 ++-- .../com/example/jpa/post/domain/Post.java | 2 +- .../post/dto/request/PostUpdateRequest.java | 7 ---- .../post/dto/response/PostAllResponse.java | 22 ++++++++++++ .../jpa/post/dto/response/PostResponse.java | 17 ++-------- .../example/jpa/post/service/PostService.java | 10 ++++-- .../jpa/repository/CommentRepository.java | 9 +++++ 15 files changed, 133 insertions(+), 44 deletions(-) create mode 100644 src/main/java/com/example/jpa/comment/dto/request/CommentUpdateRequest.java create mode 100644 src/main/java/com/example/jpa/post/dto/response/PostAllResponse.java diff --git a/src/main/java/com/example/jpa/comment/controller/CommentController.java b/src/main/java/com/example/jpa/comment/controller/CommentController.java index fed77de..06268aa 100644 --- a/src/main/java/com/example/jpa/comment/controller/CommentController.java +++ b/src/main/java/com/example/jpa/comment/controller/CommentController.java @@ -1,12 +1,15 @@ package com.example.jpa.comment.controller; import com.example.jpa.comment.dto.request.CommentCreateRequest; +import com.example.jpa.comment.dto.request.CommentUpdateRequest; import com.example.jpa.comment.dto.response.CommentResponse; import com.example.jpa.comment.service.CommentService; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequestMapping("api/comments") @RequiredArgsConstructor @@ -29,4 +32,28 @@ public ResponseEntity findOne(@PathVariable("id") Long id) { return ResponseEntity.ok(commentResponse); } + + @PatchMapping("/{id}") + public ResponseEntity update(@PathVariable("id") Long id, @RequestBody CommentUpdateRequest commentUpdateRequest) { + + commentService.update(id, commentUpdateRequest); + + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/{id}") + public ResponseEntity delete(@PathVariable("id") Long id) { + + commentService.delete(id); + + return ResponseEntity.ok().build(); + } + + @GetMapping + public ResponseEntity findAll() { + + List commentResponses = commentService.findAll(); + + return ResponseEntity.ok(commentResponses); + } } diff --git a/src/main/java/com/example/jpa/comment/domain/Comment.java b/src/main/java/com/example/jpa/comment/domain/Comment.java index c0661ae..36e3638 100644 --- a/src/main/java/com/example/jpa/comment/domain/Comment.java +++ b/src/main/java/com/example/jpa/comment/domain/Comment.java @@ -27,11 +27,18 @@ public class Comment { private String content; @Builder - public Comment(String content) { + public Comment(Member member, Post post, String content) { + this.member = member; + this.post = post; this.content = content; } - void update(String content) { + public Comment(Member member, String content) { + this.member = member; + this.content = content; + } + + public void update(String content) { this.content = content; } } diff --git a/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java b/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java index a5389c9..975df0c 100644 --- a/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java +++ b/src/main/java/com/example/jpa/comment/dto/request/CommentCreateRequest.java @@ -1,15 +1,21 @@ package com.example.jpa.comment.dto.request; import com.example.jpa.comment.domain.Comment; +import com.example.jpa.member.domain.Member; +import com.example.jpa.post.domain.Post; import lombok.Getter; @Getter public class CommentCreateRequest { + private Long member; + private Long post; private String content; - public Comment toEntity() { + public Comment toEntity(Member member, Post post) { return Comment.builder() + .member(member) + .post(post) .content(this.content) .build(); } diff --git a/src/main/java/com/example/jpa/comment/dto/request/CommentUpdateRequest.java b/src/main/java/com/example/jpa/comment/dto/request/CommentUpdateRequest.java new file mode 100644 index 0000000..a018a5a --- /dev/null +++ b/src/main/java/com/example/jpa/comment/dto/request/CommentUpdateRequest.java @@ -0,0 +1,10 @@ +package com.example.jpa.comment.dto.request; + +import lombok.Getter; + +@Getter +public class CommentUpdateRequest { + + private String content; + +} diff --git a/src/main/java/com/example/jpa/comment/service/CommentService.java b/src/main/java/com/example/jpa/comment/service/CommentService.java index 459a9ba..13527ca 100644 --- a/src/main/java/com/example/jpa/comment/service/CommentService.java +++ b/src/main/java/com/example/jpa/comment/service/CommentService.java @@ -2,30 +2,60 @@ import com.example.jpa.comment.domain.Comment; import com.example.jpa.comment.dto.request.CommentCreateRequest; +import com.example.jpa.comment.dto.request.CommentUpdateRequest; import com.example.jpa.comment.dto.response.CommentResponse; +import com.example.jpa.member.domain.Member; +import com.example.jpa.post.domain.Post; import com.example.jpa.repository.CommentRepository; +import com.example.jpa.repository.MemberRepository; +import com.example.jpa.repository.PostRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.NoSuchElementException; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class CommentService { private final CommentRepository commentRepository; + private final MemberRepository memberRepository; + private final PostRepository postRepository; @Transactional public void create(CommentCreateRequest commentCreateRequest) { - commentRepository.save(commentCreateRequest.toEntity()); + Member member = memberRepository.findById(commentCreateRequest.getMember()).get(); + Post post = postRepository.findById(commentCreateRequest.getPost()).get(); + commentRepository.save(commentCreateRequest.toEntity(member, post)); } @Transactional(readOnly = true) public CommentResponse findOne(Long id) { Comment comment = commentRepository.findById(id) - .orElseThrow(() -> new NoSuchElementException("멤버가 존재하지 않습니다.")); + .orElseThrow(() -> new NoSuchElementException("댓글이 존재하지 않습니다.")); return CommentResponse.from(comment); } + + @Transactional + public void update(Long id, CommentUpdateRequest commentUpdateRequest) { + Comment comment = commentRepository.findById(id) + .orElseThrow(() -> new NoSuchElementException("댓글이 존재하지 않습니다.")); + comment.update(commentUpdateRequest.getContent()); + } + + @Transactional + public void delete(Long id) { + commentRepository.deleteById(id); + } + + @Transactional(readOnly = true) + public List findAll() { + return commentRepository.findAll().stream() + .map(CommentResponse::from) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/com/example/jpa/member/domain/Member.java b/src/main/java/com/example/jpa/member/domain/Member.java index 978a7d7..356f9b6 100644 --- a/src/main/java/com/example/jpa/member/domain/Member.java +++ b/src/main/java/com/example/jpa/member/domain/Member.java @@ -22,10 +22,10 @@ public class Member { private String name; - @OneToMany(mappedBy = "member", orphanRemoval = true) + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private List posts = new ArrayList<>(); - @OneToMany(mappedBy = "member", orphanRemoval = true) + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private List comments = new ArrayList<>(); @Builder diff --git a/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java b/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java index 37cf0e4..b98ce00 100644 --- a/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java +++ b/src/main/java/com/example/jpa/member/dto/request/MemberUpdateRequest.java @@ -1,6 +1,5 @@ package com.example.jpa.member.dto.request; -import com.example.jpa.member.domain.Member; import lombok.Getter; @Getter @@ -8,9 +7,4 @@ public class MemberUpdateRequest { private String name; - public Member toEntity() { - return Member.builder() - .name(this.name) - .build(); - } } diff --git a/src/main/java/com/example/jpa/member/service/MemberService.java b/src/main/java/com/example/jpa/member/service/MemberService.java index 27fae85..2e259c8 100644 --- a/src/main/java/com/example/jpa/member/service/MemberService.java +++ b/src/main/java/com/example/jpa/member/service/MemberService.java @@ -4,13 +4,10 @@ import com.example.jpa.member.dto.request.MemberCreateRequest; import com.example.jpa.member.dto.request.MemberUpdateRequest; import com.example.jpa.member.dto.response.MemberResponse; -import com.example.jpa.post.domain.Post; -import com.example.jpa.post.dto.request.PostUpdateRequest; import com.example.jpa.repository.MemberRepository; import java.util.List; import java.util.NoSuchElementException; -import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/example/jpa/post/controller/PostController.java b/src/main/java/com/example/jpa/post/controller/PostController.java index c8dfddf..de1ce46 100644 --- a/src/main/java/com/example/jpa/post/controller/PostController.java +++ b/src/main/java/com/example/jpa/post/controller/PostController.java @@ -2,6 +2,7 @@ import com.example.jpa.post.dto.request.PostCreateRequest; import com.example.jpa.post.dto.request.PostUpdateRequest; +import com.example.jpa.post.dto.response.PostAllResponse; import com.example.jpa.post.dto.response.PostResponse; import com.example.jpa.post.service.PostService; import lombok.RequiredArgsConstructor; @@ -34,7 +35,7 @@ public ResponseEntity findOne(@PathVariable("id") Long id) { } @PatchMapping("/{id}") - public ResponseEntity update(@PathVariable("id") Long id, @RequestBody PostUpdateRequest postUpdateRequest) { + public ResponseEntity update(@PathVariable("id") Long id, @RequestBody PostUpdateRequest postUpdateRequest) { postService.update(id, postUpdateRequest); @@ -42,7 +43,7 @@ public ResponseEntity update(@PathVariable("id") Long id, @Request } @DeleteMapping("/{id}") - public ResponseEntity delete(@PathVariable("id") Long id) { + public ResponseEntity delete(@PathVariable("id") Long id) { postService.delete(id); @@ -52,7 +53,7 @@ public ResponseEntity delete(@PathVariable("id") Long id) { @GetMapping public ResponseEntity findAll() { - List postResponses = postService.findAll(); + List postResponses = postService.findAll(); return ResponseEntity.ok(postResponses); } diff --git a/src/main/java/com/example/jpa/post/domain/Post.java b/src/main/java/com/example/jpa/post/domain/Post.java index f0ec41e..ee949ee 100644 --- a/src/main/java/com/example/jpa/post/domain/Post.java +++ b/src/main/java/com/example/jpa/post/domain/Post.java @@ -27,7 +27,7 @@ public class Post { private String title; private String content; - @OneToMany(mappedBy = "post", orphanRemoval = true) + @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true) private List comments = new ArrayList<>(); @Builder diff --git a/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java b/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java index 8d23345..3b351a4 100644 --- a/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java +++ b/src/main/java/com/example/jpa/post/dto/request/PostUpdateRequest.java @@ -1,6 +1,5 @@ package com.example.jpa.post.dto.request; -import com.example.jpa.post.domain.Post; import lombok.Getter; @Getter @@ -9,10 +8,4 @@ public class PostUpdateRequest { private String title; private String content; - public Post toEntity() { - return Post.builder() - .title(this.title) - .content(this.content) - .build(); - } } diff --git a/src/main/java/com/example/jpa/post/dto/response/PostAllResponse.java b/src/main/java/com/example/jpa/post/dto/response/PostAllResponse.java new file mode 100644 index 0000000..3beda96 --- /dev/null +++ b/src/main/java/com/example/jpa/post/dto/response/PostAllResponse.java @@ -0,0 +1,22 @@ +package com.example.jpa.post.dto.response; + +import com.example.jpa.post.domain.Post; +import lombok.Getter; + +@Getter +public class PostAllResponse { + + private Long id; + private String title; + private String content; + + public PostAllResponse(Long id, String title, String content) { + this.id = id; + this.title = title; + this.content = content; + } + + public static PostAllResponse from(Post post) { + return new PostAllResponse(post.getId(), post.getTitle(), post.getContent()); + } +} diff --git a/src/main/java/com/example/jpa/post/dto/response/PostResponse.java b/src/main/java/com/example/jpa/post/dto/response/PostResponse.java index 5dadefd..4d92184 100644 --- a/src/main/java/com/example/jpa/post/dto/response/PostResponse.java +++ b/src/main/java/com/example/jpa/post/dto/response/PostResponse.java @@ -1,7 +1,5 @@ package com.example.jpa.post.dto.response; -import com.example.jpa.comment.domain.Comment; -import com.example.jpa.member.domain.Member; import com.example.jpa.post.domain.Post; import lombok.Getter; @@ -14,9 +12,9 @@ public class PostResponse { private String title; private String name; private String content; - private List comments; + private List comments; - public PostResponse(Long id, String title, String name, String content, List comments) { + public PostResponse(Long id, String title, String name, String content, List comments) { this.id = id; this.title = title; this.name = name; @@ -24,17 +22,8 @@ public PostResponse(Long id, String title, String name, String content, List comments) { + public static PostResponse from(Post post, String name, List comments) { return new PostResponse(post.getId(), post.getTitle(), name, post.getContent(), comments); } - public static PostResponse from(Post post) { - return new PostResponse(post.getId(), post.getTitle(), post.getContent()); - } } diff --git a/src/main/java/com/example/jpa/post/service/PostService.java b/src/main/java/com/example/jpa/post/service/PostService.java index 2f74894..d0062a4 100644 --- a/src/main/java/com/example/jpa/post/service/PostService.java +++ b/src/main/java/com/example/jpa/post/service/PostService.java @@ -5,6 +5,7 @@ import com.example.jpa.post.domain.Post; import com.example.jpa.post.dto.request.PostCreateRequest; import com.example.jpa.post.dto.request.PostUpdateRequest; +import com.example.jpa.post.dto.response.PostAllResponse; import com.example.jpa.post.dto.response.PostResponse; import com.example.jpa.repository.CommentRepository; import com.example.jpa.repository.MemberRepository; @@ -35,7 +36,10 @@ public void create(PostCreateRequest postCreateRequest) { public PostResponse findOne(Long id) { Post post = postRepository.findById(id) .orElseThrow(() -> new NoSuchElementException("게시글이 존재하지 않습니다.")); - List comments = commentRepository.findAll().stream().toList(); + List comments = commentRepository.findByPostID(id) + .stream() + .map(Comment::getContent) + .collect(Collectors.toList()); return PostResponse.from(post, post.getMember().getName(), comments); } @@ -53,9 +57,9 @@ public void delete(Long id) { } @Transactional(readOnly = true) - public List findAll() { + public List findAll() { return postRepository.findAll().stream() - .map(PostResponse::from) + .map(PostAllResponse::from) .collect(Collectors.toList()); } } diff --git a/src/main/java/com/example/jpa/repository/CommentRepository.java b/src/main/java/com/example/jpa/repository/CommentRepository.java index 152de0e..802401c 100644 --- a/src/main/java/com/example/jpa/repository/CommentRepository.java +++ b/src/main/java/com/example/jpa/repository/CommentRepository.java @@ -2,6 +2,15 @@ import com.example.jpa.comment.domain.Comment; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; public interface CommentRepository extends JpaRepository { + @Query("select new com.example.jpa.comment.domain.Comment(c.member, c.content) " + + "from Comment c " + + "where c.post.id = :id") + List findByPostID(@Param("id") Long id); + }