diff --git a/src/main/java/com/example/devSns/controllers/PostController.java b/src/main/java/com/example/devSns/controllers/PostController.java index bfc52d3..2534399 100644 --- a/src/main/java/com/example/devSns/controllers/PostController.java +++ b/src/main/java/com/example/devSns/controllers/PostController.java @@ -2,9 +2,7 @@ import com.example.devSns.dto.PostDTO; import com.example.devSns.dto.PostResponse; -import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; -import org.springframework.dao.DataAccessException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -23,9 +21,9 @@ public ResponseEntity> showPosts() { return new ResponseEntity<>(posts, HttpStatus.OK); } - @GetMapping("/show/{username}") - public ResponseEntity> showPost(@PathVariable String username) { - List post = postService.findByUsername(username); + @GetMapping("/show/{userID}") + public ResponseEntity> showPost(@PathVariable Long userID) { + List post = postService.findByUserID(userID); return new ResponseEntity<>(post, HttpStatus.OK); } @@ -46,18 +44,4 @@ public ResponseEntity deletePost(@PathVariable Long id) { postService.delete(id); return new ResponseEntity<>("Post deleted", HttpStatus.OK); } - - @ExceptionHandler - public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e) { - ResponseEntity response = - new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); - return response; - } - - @ExceptionHandler - public ResponseEntity handleDataAccessException(DataAccessException e) { - ResponseEntity response = - new ResponseEntity<>("DB 오류", HttpStatus.INTERNAL_SERVER_ERROR); - return response; - } } diff --git a/src/main/java/com/example/devSns/controllers/ReplyController.java b/src/main/java/com/example/devSns/controllers/ReplyController.java new file mode 100644 index 0000000..cc1c352 --- /dev/null +++ b/src/main/java/com/example/devSns/controllers/ReplyController.java @@ -0,0 +1,46 @@ +package com.example.devSns.controllers; + +import com.example.devSns.dto.ReplyDTO; +import com.example.devSns.dto.ReplyResponse; +import com.example.devSns.services.ReplyService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping +@RequiredArgsConstructor +public class ReplyController { + private final ReplyService replyService; + + @GetMapping("/{postId}/replies") + public ResponseEntity> getReplies(@PathVariable long postId) { + List replies = replyService.replyGetAll(postId); + ResponseEntity> responseEntity = new ResponseEntity<>(replies, HttpStatus.OK); + return responseEntity; + } + + @PostMapping("/{postId}") + public ResponseEntity writeReply(@PathVariable long postId, long userId, ReplyDTO reply) { + ReplyResponse replyResponse = replyService.writeReply(postId, userId, reply); + ResponseEntity responseEntity = new ResponseEntity<>(replyResponse, HttpStatus.OK); + return responseEntity; + } + + @PatchMapping("/{postid}") + public ResponseEntity updateReply(@PathVariable long postId, long userId, ReplyDTO reply) { + ReplyResponse replyResponse = replyService.updateReply(postId, userId, reply); + ResponseEntity responseEntity = new ResponseEntity<>(replyResponse, HttpStatus.OK); + return responseEntity; + } + + @DeleteMapping("/{postId}") + public ResponseEntity deleteReply(@PathVariable long postId, long userId) { + String deleteCheck = replyService.deleteReply(postId, userId); + ResponseEntity responseEntity = new ResponseEntity<>(deleteCheck, HttpStatus.OK); + return responseEntity; + } +} diff --git a/src/main/java/com/example/devSns/dto/PostDTO.java b/src/main/java/com/example/devSns/dto/PostDTO.java index c3cc3cc..118ec9c 100644 --- a/src/main/java/com/example/devSns/dto/PostDTO.java +++ b/src/main/java/com/example/devSns/dto/PostDTO.java @@ -1,6 +1,18 @@ package com.example.devSns.dto; +import com.example.devSns.entities.Posts; +import com.example.devSns.entities.Users; + public record PostDTO( + Long userId, String username, String content -) { } +) { + public static Posts dtoToEntity(PostDTO postDTO, Users user) { + Posts postEntity = Posts.builder() + .users(user) + .content(postDTO.content()) + .build(); + return postEntity; + } +} diff --git a/src/main/java/com/example/devSns/dto/PostResponse.java b/src/main/java/com/example/devSns/dto/PostResponse.java index c8ff865..467fd48 100644 --- a/src/main/java/com/example/devSns/dto/PostResponse.java +++ b/src/main/java/com/example/devSns/dto/PostResponse.java @@ -1,5 +1,7 @@ package com.example.devSns.dto; +import com.example.devSns.entities.Posts; +import com.example.devSns.entities.Users; import lombok.*; import java.time.LocalDateTime; @@ -12,4 +14,15 @@ public record PostResponse( Integer like, LocalDateTime createAt, LocalDateTime updateAt -) {} +) { + public static PostResponse entityToDto(Posts post) { + return PostResponse.builder() + .id(post.getId()) + .username(post.getUsers().getUsername()) + .content(post.getContent()) + .like(post.getLikeit()) + .createAt(post.getCreateat()) + .updateAt(post.getUpdateat()) + .build(); + } +} diff --git a/src/main/java/com/example/devSns/dto/ReplyDTO.java b/src/main/java/com/example/devSns/dto/ReplyDTO.java new file mode 100644 index 0000000..c557f8f --- /dev/null +++ b/src/main/java/com/example/devSns/dto/ReplyDTO.java @@ -0,0 +1,19 @@ +package com.example.devSns.dto; + +import com.example.devSns.entities.Posts; +import com.example.devSns.entities.Replies; +import com.example.devSns.entities.Users; + +import java.util.Optional; + +public record ReplyDTO( + String comment +) { + public static Replies dtoToEntity(Posts post, Users user, ReplyDTO replyDTO) { + return Replies.builder() + .posts(post) + .users(user) + .reply(replyDTO.comment()) + .build(); + } +} diff --git a/src/main/java/com/example/devSns/dto/ReplyResponse.java b/src/main/java/com/example/devSns/dto/ReplyResponse.java new file mode 100644 index 0000000..a5b6b21 --- /dev/null +++ b/src/main/java/com/example/devSns/dto/ReplyResponse.java @@ -0,0 +1,19 @@ +package com.example.devSns.dto; + +import com.example.devSns.entities.Replies; +import lombok.Builder; + +@Builder +public record ReplyResponse( + long replyId, + String username, + String comment +) { + public static ReplyResponse entityToDTO(Replies replies) { + return ReplyResponse.builder() + .replyId(replies.getId()) + .username(replies.getUsers().getUsername()) + .comment(replies.getReply()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/entities/Posts.java b/src/main/java/com/example/devSns/entities/Posts.java index 60e2789..87fa483 100644 --- a/src/main/java/com/example/devSns/entities/Posts.java +++ b/src/main/java/com/example/devSns/entities/Posts.java @@ -8,7 +8,6 @@ @Entity @Getter -@Setter @NoArgsConstructor @AllArgsConstructor @Builder @@ -21,9 +20,10 @@ public class Posts { @Column private String content; + @JoinColumn(name = "users_id") + @ManyToOne @NotNull - @Column - private String username; + private Users users; @Column private int likeit; @@ -33,4 +33,16 @@ public class Posts { @Column private LocalDateTime updateat; + + public void setCreateat(LocalDateTime createat) { + this.createat = createat; + } + + public void setUpdateat(LocalDateTime updateat) { + this.updateat = updateat; + } + + public void setContent(String content) { + this.content = content; + } } diff --git a/src/main/java/com/example/devSns/entities/Replies.java b/src/main/java/com/example/devSns/entities/Replies.java new file mode 100644 index 0000000..e703199 --- /dev/null +++ b/src/main/java/com/example/devSns/entities/Replies.java @@ -0,0 +1,42 @@ +package com.example.devSns.entities; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Builder +public class Replies { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + @JoinColumn(name = "posts_id") + @ManyToOne + @NotNull + private Posts posts; + + @JoinColumn(name = "users_id") + @ManyToOne + @NotNull + private Users users; + + @NotNull + private String reply; + + @NotNull + private LocalDateTime createAt; + + @NotNull + private LocalDateTime updateAt; + + @OneToMany(mappedBy = "posts", cascade = CascadeType.REMOVE, orphanRemoval = true) + private List replies = new ArrayList<>(); +} diff --git a/src/main/java/com/example/devSns/entities/Users.java b/src/main/java/com/example/devSns/entities/Users.java new file mode 100644 index 0000000..600fb2a --- /dev/null +++ b/src/main/java/com/example/devSns/entities/Users.java @@ -0,0 +1,29 @@ +package com.example.devSns.entities; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Builder +public class Users { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + @NotNull + private String username; + + @NotNull + private Integer age; + + private Date birthday; +} diff --git a/src/main/java/com/example/devSns/repositories/PostRepository.java b/src/main/java/com/example/devSns/repositories/PostRepository.java index 44dc0f1..eeaaae1 100644 --- a/src/main/java/com/example/devSns/repositories/PostRepository.java +++ b/src/main/java/com/example/devSns/repositories/PostRepository.java @@ -9,5 +9,5 @@ public interface PostRepository extends JpaRepository { public List findAll(); public Optional findById(Integer id); - public List findByUsername(String username); + public List findByUsersId(Long userID); } diff --git a/src/main/java/com/example/devSns/repositories/ReplyRepository.java b/src/main/java/com/example/devSns/repositories/ReplyRepository.java new file mode 100644 index 0000000..d8fc040 --- /dev/null +++ b/src/main/java/com/example/devSns/repositories/ReplyRepository.java @@ -0,0 +1,11 @@ +package com.example.devSns.repositories; + +import com.example.devSns.entities.Posts; +import com.example.devSns.entities.Replies; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ReplyRepository extends JpaRepository { + public List findByPosts(Posts posts); +} diff --git a/src/main/java/com/example/devSns/repositories/UserRepository.java b/src/main/java/com/example/devSns/repositories/UserRepository.java new file mode 100644 index 0000000..9be1992 --- /dev/null +++ b/src/main/java/com/example/devSns/repositories/UserRepository.java @@ -0,0 +1,8 @@ +package com.example.devSns.repositories; + +import com.example.devSns.entities.Users; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + public Users findById(long userId); +} diff --git a/src/main/java/com/example/devSns/services/PostService.java b/src/main/java/com/example/devSns/services/PostService.java index 13958ab..a444aac 100644 --- a/src/main/java/com/example/devSns/services/PostService.java +++ b/src/main/java/com/example/devSns/services/PostService.java @@ -3,6 +3,8 @@ import com.example.devSns.dto.PostDTO; import com.example.devSns.dto.PostResponse; import com.example.devSns.entities.Posts; +import com.example.devSns.entities.Users; +import com.example.devSns.repositories.UserRepository; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -13,33 +15,19 @@ import java.util.ArrayList; import java.util.List; +import static com.example.devSns.dto.PostDTO.dtoToEntity; +import static com.example.devSns.dto.PostResponse.entityToDto; + @Service @RequiredArgsConstructor public class PostService { private final PostRepository postRepository; - - public Posts dtoToEntity(PostDTO postDTO) { - Posts postEntity = Posts.builder() - .username(postDTO.username()) - .content(postDTO.content()) - .build(); - return postEntity; - } - - public PostResponse entityToDto(Posts post) { - return PostResponse.builder() - .id(post.getId()) - .username(post.getUsername()) - .content(post.getContent()) - .like(post.getLikeit()) - .createAt(post.getCreateat()) - .updateAt(post.getUpdateat()) - .build(); - } + private final UserRepository userRepository; @Transactional // 트랜잭션 보장 - public PostResponse save(PostDTO postDTO) { // post insert - Posts postEntity = dtoToEntity(postDTO); + public PostResponse save(PostDTO postDTO) { + Users user = userRepository.findById(postDTO.userId()).orElseThrow(EntityNotFoundException::new); + Posts postEntity = dtoToEntity(postDTO, user); postEntity.setCreateat(LocalDateTime.now()); Posts resultEntity = postRepository.save(postEntity); return entityToDto(resultEntity); @@ -56,8 +44,8 @@ public List findAll() { // 전체 post 조회 } @Transactional - public List findByUsername(String username) { // 작성자 기준 post 조회 - List postsByName = postRepository.findByUsername(username); + public List findByUserID(Long userID) { // 작성자 기준 post 조회 + List postsByName = postRepository.findByUsersId(userID); List postResponses = new ArrayList<>(); for (Posts post : postsByName) { postResponses.add(entityToDto(post)); diff --git a/src/main/java/com/example/devSns/services/ReplyService.java b/src/main/java/com/example/devSns/services/ReplyService.java new file mode 100644 index 0000000..7bc83bc --- /dev/null +++ b/src/main/java/com/example/devSns/services/ReplyService.java @@ -0,0 +1,63 @@ +package com.example.devSns.services; + +import com.example.devSns.dto.ReplyDTO; +import com.example.devSns.dto.ReplyResponse; +import com.example.devSns.entities.Posts; +import com.example.devSns.entities.Replies; +import com.example.devSns.entities.Users; +import com.example.devSns.repositories.PostRepository; +import com.example.devSns.repositories.ReplyRepository; +import com.example.devSns.repositories.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.PathVariable; + +import java.util.ArrayList; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class ReplyService { + private final ReplyRepository replyRepository; + private final PostRepository postRepository; + private final UserRepository userRepository; + + @Transactional + public List replyGetAll(@PathVariable long postId) { + Posts post = postRepository.findById(postId).orElseThrow(); + List replies = replyRepository.findByPosts(post); + List repliesResponse = new ArrayList<>(); + for (Replies reply: replies) { + repliesResponse.add(ReplyResponse.entityToDTO(reply)); + } + return repliesResponse; + } + + @Transactional + public ReplyResponse writeReply(@PathVariable long postId, long userId, ReplyDTO reply) { + Posts post = postRepository.findById(postId).orElseThrow(); + Users user = userRepository.findById(userId); + Replies replyEntity = ReplyDTO.dtoToEntity(post, user, reply); + replyRepository.save(replyEntity); + return ReplyResponse.entityToDTO(replyEntity); + } + + @Transactional + public ReplyResponse updateReply(@PathVariable long postId, long userId, ReplyDTO reply) { + Posts post = postRepository.findById(postId).orElseThrow(); + Users user = userRepository.findById(userId); + Replies replyEntity = ReplyDTO.dtoToEntity(post, user, reply); + replyRepository.save(replyEntity); + return ReplyResponse.entityToDTO(replyEntity); + } + + @Transactional + public String deleteReply(@PathVariable long postId, long userId) { + Posts post = postRepository.findById(postId).orElseThrow(); + Users user = userRepository.findById(userId); + Replies replyEntity = replyRepository.findById(postId).orElseThrow(); + replyRepository.delete(replyEntity); + return "성공적으로 삭제되었습니다"; + } +} diff --git a/src/main/java/exceptions/GlobalExceptionHandler.java b/src/main/java/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000..9e7eaad --- /dev/null +++ b/src/main/java/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,26 @@ +package exceptions; + +import jakarta.persistence.EntityNotFoundException; +import org.springframework.dao.DataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@RestControllerAdvice +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + @ExceptionHandler + public ResponseEntity handleEntityNotFoundException(EntityNotFoundException e) { + ResponseEntity response = + new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + return response; + } + + @ExceptionHandler + public ResponseEntity handleDataAccessException(DataAccessException e) { + ResponseEntity response = + new ResponseEntity<>("DB 오류", HttpStatus.INTERNAL_SERVER_ERROR); + return response; + } +}