diff --git a/.gitignore b/.gitignore index c2065bc..6ac14b0 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ out/ ### VS Code ### .vscode/ + +# .gitignore 파일에 추가 +application.yml \ No newline at end of file diff --git a/src/main/java/com/example/springhw32/controller/CommentController.java b/src/main/java/com/example/springhw32/controller/CommentController.java index 0ee065d..a594498 100644 --- a/src/main/java/com/example/springhw32/controller/CommentController.java +++ b/src/main/java/com/example/springhw32/controller/CommentController.java @@ -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 +@RequestMapping("/posts/comments") +@RequiredArgsConstructor public class CommentController { + private final CommentService commentService; + + // 댓글 작성 + @PostMapping("/{postId}") + public CommentDto createComment(@RequestBody CommentDto commentDto, @PathVariable Long postId) { + return commentService.createComment(commentDto, postId); + } + + // 특정 게시물에 달린 모든 댓글 조회 + @GetMapping("/{postId}") + public List getAllCommentsByPostId(@PathVariable Long postId) { + return commentService.getAllCommentsByPostId(postId); + } } diff --git a/src/main/java/com/example/springhw32/controller/PostController.java b/src/main/java/com/example/springhw32/controller/PostController.java index 317774b..eea12e4 100644 --- a/src/main/java/com/example/springhw32/controller/PostController.java +++ b/src/main/java/com/example/springhw32/controller/PostController.java @@ -1,5 +1,39 @@ 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 +@RequestMapping("/posts") +@RequiredArgsConstructor public class PostController { + private final PostService postService; + + // 글 작성 + @PostMapping + public PostDto createPost(@RequestBody PostDto postDto, @RequestParam String writer) { + return postService.createPost(postDto, writer); + } + // 최신순 글 조회 + @GetMapping + public List getPostsSortedByDate() { + return postService.getPostsSortedByDate(); + } + + // 작성자 글 조회 + @GetMapping("/{writer}") + public List getPostsByWriter(@PathVariable String writer) { + return postService.getPostsByWriter(writer); + } + + // 댓글 많은 순 글 조회 + @GetMapping("/comments") + public List getPostsSortedByComments() { + return postService.getPostsSortedByComments(); + } } diff --git a/src/main/java/com/example/springhw32/controller/UserController.java b/src/main/java/com/example/springhw32/controller/UserController.java index 3b321ac..54e80cb 100644 --- a/src/main/java/com/example/springhw32/controller/UserController.java +++ b/src/main/java/com/example/springhw32/controller/UserController.java @@ -1,5 +1,27 @@ 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.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/users") public class UserController { -} + private final UserService userService; + + @PostMapping + public UserDto join(@ModelAttribute UserDto userDto) { + return userService.join(userDto); + } + + @PostMapping("/login") + public String login(@ModelAttribute UserDto userDto) { + return userService.login(userDto); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw32/dto/CommentDto.java b/src/main/java/com/example/springhw32/dto/CommentDto.java index a9d04fa..39cc8af 100644 --- a/src/main/java/com/example/springhw32/dto/CommentDto.java +++ b/src/main/java/com/example/springhw32/dto/CommentDto.java @@ -1,5 +1,16 @@ package com.example.springhw32.dto; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter public class CommentDto { + private Long commentId; + + private Long postId; + + private Long userId; + private String content; } diff --git a/src/main/java/com/example/springhw32/dto/PostDto.java b/src/main/java/com/example/springhw32/dto/PostDto.java index cde1eda..41b7a4f 100644 --- a/src/main/java/com/example/springhw32/dto/PostDto.java +++ b/src/main/java/com/example/springhw32/dto/PostDto.java @@ -1,5 +1,24 @@ package com.example.springhw32.dto; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter public class PostDto { + private Long postId; + + private String title; + + private String content; + + private String writer; + + private Long commentCount; + + private LocalDateTime createdAt; + private LocalDateTime updatedAt; } diff --git a/src/main/java/com/example/springhw32/dto/UserDto.java b/src/main/java/com/example/springhw32/dto/UserDto.java index cbbbe2e..bc5192d 100644 --- a/src/main/java/com/example/springhw32/dto/UserDto.java +++ b/src/main/java/com/example/springhw32/dto/UserDto.java @@ -1,5 +1,19 @@ package com.example.springhw32.dto; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor public class UserDto { + private Long userId; + + private String username; + + private String password; + + private String nickname; -} +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw32/entity/Comment.java b/src/main/java/com/example/springhw32/entity/Comment.java index be818a0..2445f21 100644 --- a/src/main/java/com/example/springhw32/entity/Comment.java +++ b/src/main/java/com/example/springhw32/entity/Comment.java @@ -1,5 +1,25 @@ 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 commentId; + + @Column(nullable = false) + private String content; + + @ManyToOne + @JoinColumn(name = "userId", nullable = false) + private User user; + + @ManyToOne + private Post post; } diff --git a/src/main/java/com/example/springhw32/entity/Post.java b/src/main/java/com/example/springhw32/entity/Post.java index 38b5e81..e3fb445 100644 --- a/src/main/java/com/example/springhw32/entity/Post.java +++ b/src/main/java/com/example/springhw32/entity/Post.java @@ -1,5 +1,32 @@ package com.example.springhw32.entity; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Entity public class Post { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long postId; + + @ManyToOne + private User user; + + @Column(nullable = false) + private String title; + + @Column(nullable = false) + private String content; + + private Long commentCount = 0L; + + private LocalDateTime createdAt; + + private LocalDateTime updatedAt; } diff --git a/src/main/java/com/example/springhw32/entity/User.java b/src/main/java/com/example/springhw32/entity/User.java index 447989d..af06838 100644 --- a/src/main/java/com/example/springhw32/entity/User.java +++ b/src/main/java/com/example/springhw32/entity/User.java @@ -1,5 +1,25 @@ 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, unique = true) + private String username; + + @Column(nullable = false) + private String password; + + @Column(nullable = false, unique = true) + private String nickname; + +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw32/repository/CommentRepository.java b/src/main/java/com/example/springhw32/repository/CommentRepository.java index 83dcd99..8dea649 100644 --- a/src/main/java/com/example/springhw32/repository/CommentRepository.java +++ b/src/main/java/com/example/springhw32/repository/CommentRepository.java @@ -1,5 +1,12 @@ package com.example.springhw32.repository; -public interface CommentRepository { +import com.example.springhw32.entity.Comment; +import com.example.springhw32.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; -} +import java.util.List; + +public interface CommentRepository extends JpaRepository { + // 특정 게시물에 달린 모든 댓글 조회 + List findByPost_PostId(Long postId); +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw32/repository/PostRepository.java b/src/main/java/com/example/springhw32/repository/PostRepository.java index 14b8546..93ccb18 100644 --- a/src/main/java/com/example/springhw32/repository/PostRepository.java +++ b/src/main/java/com/example/springhw32/repository/PostRepository.java @@ -1,5 +1,13 @@ package com.example.springhw32.repository; -public interface PostRepository { +import com.example.springhw32.entity.Post; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + +public interface PostRepository extends JpaRepository { + List findByUser_Nickname(String nickname); + List findAllByOrderByCreatedAtDesc(); + List findAllByOrderByCommentCountDesc(); } + diff --git a/src/main/java/com/example/springhw32/repository/UserRepository.java b/src/main/java/com/example/springhw32/repository/UserRepository.java index 877a215..8de1316 100644 --- a/src/main/java/com/example/springhw32/repository/UserRepository.java +++ b/src/main/java/com/example/springhw32/repository/UserRepository.java @@ -1,5 +1,18 @@ package com.example.springhw32.repository; -public interface UserRepository { +import com.example.springhw32.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import java.util.Optional; + +@Repository +public interface UserRepository extends JpaRepository { + User findByUsername(String username); + + boolean existsByUsername(String username); + + boolean existsByNickname(String nickname); + + Optional findByNickname(String nickname); } diff --git a/src/main/java/com/example/springhw32/service/CommentService.java b/src/main/java/com/example/springhw32/service/CommentService.java index ec0c937..b8b1df8 100644 --- a/src/main/java/com/example/springhw32/service/CommentService.java +++ b/src/main/java/com/example/springhw32/service/CommentService.java @@ -1,5 +1,61 @@ package com.example.springhw32.service; +import com.example.springhw32.dto.CommentDto; +import com.example.springhw32.entity.Comment; +import com.example.springhw32.entity.Post; +import com.example.springhw32.entity.User; +import com.example.springhw32.repository.CommentRepository; +import com.example.springhw32.repository.PostRepository; +import com.example.springhw32.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.NoSuchElementException; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor public class CommentService { + private final CommentRepository commentRepository; + private final PostRepository postRepository; + private final UserRepository userRepository; + + @Transactional + public CommentDto createComment(CommentDto commentDto, Long postId) { + Post post = postRepository.findById(postId) + .orElseThrow(() -> new NoSuchElementException("Post not found")); + + User user = userRepository.findById(commentDto.getUserId()) + .orElseThrow(() -> new NoSuchElementException("User not found")); + + Comment comment = new Comment(); + comment.setContent(commentDto.getContent()); + comment.setUser(user); + comment.setPost(post); + commentRepository.save(comment); + post.setCommentCount(post.getCommentCount() + 1L); + postRepository.save(post); + return mapToDto(comment); + } + + + // 특정 게시물에 달린 모든 댓글 조회 + public List getAllCommentsByPostId(Long postId) { + return commentRepository.findByPost_PostId(postId).stream() + .map(this::mapToDto) + .collect(Collectors.toList()); + } + + // Comment -> CommentDto 변환 + private CommentDto mapToDto(Comment comment) { + CommentDto dto = new CommentDto(); + dto.setCommentId(comment.getCommentId()); + dto.setPostId(comment.getPost().getPostId()); + dto.setUserId(comment.getUser().getId()); + dto.setContent(comment.getContent()); + return dto; + } } diff --git a/src/main/java/com/example/springhw32/service/PostService.java b/src/main/java/com/example/springhw32/service/PostService.java index b029d55..98c2964 100644 --- a/src/main/java/com/example/springhw32/service/PostService.java +++ b/src/main/java/com/example/springhw32/service/PostService.java @@ -1,5 +1,71 @@ 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, String writer) { + User user = userRepository.findByNickname(writer) + .orElseThrow(() -> new IllegalArgumentException("User not found")); + + Post post = new Post(); + post.setUser(user); + post.setTitle(postDto.getTitle()); + post.setContent(postDto.getContent()); + post.setCreatedAt(LocalDateTime.now()); + post.setUpdatedAt(LocalDateTime.now()); + postRepository.save(post); + + return mapToDto(post); + } + + // 최신순 글 조회 + public List getPostsSortedByDate() { + return postRepository.findAllByOrderByCreatedAtDesc().stream() + .map(this::mapToDto) + .collect(Collectors.toList()); + } + + // 작성자 글 조회 + public List getPostsByWriter(String writer) { + return postRepository.findByUser_Nickname(writer).stream() + .map(this::mapToDto) + .collect(Collectors.toList()); + } + + // 댓글 많은 순 글 조회 + public List getPostsSortedByComments() { + return postRepository.findAllByOrderByCommentCountDesc().stream() + .map(this::mapToDto) + .collect(Collectors.toList()); + } + + // Post -> PostDto 변환 + private PostDto mapToDto(Post post) { + PostDto dto = new PostDto(); + dto.setPostId(post.getPostId()); + dto.setTitle(post.getTitle()); + dto.setContent(post.getContent()); + dto.setWriter(post.getUser().getNickname()); + dto.setCommentCount(post.getCommentCount()); + dto.setCreatedAt(post.getCreatedAt()); + dto.setUpdatedAt(post.getUpdatedAt()); + return dto; + } } diff --git a/src/main/java/com/example/springhw32/service/UserService.java b/src/main/java/com/example/springhw32/service/UserService.java index 8badccf..f8a0882 100644 --- a/src/main/java/com/example/springhw32/service/UserService.java +++ b/src/main/java/com/example/springhw32/service/UserService.java @@ -1,5 +1,56 @@ package com.example.springhw32.service; +import com.example.springhw32.dto.UserDto; +import com.example.springhw32.entity.User; +import com.example.springhw32.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.NoSuchElementException; + +@Service +@RequiredArgsConstructor public class UserService { + private final UserRepository userRepository; + + @Transactional + public UserDto join(UserDto userDto) { + + if (userDto.getUsername().isBlank()) { + throw new NoSuchElementException("아이디를 입력해 주세요."); + } + if (userDto.getPassword().isBlank()) { + throw new NoSuchElementException("비밀번호를 입력해 주세요."); + } + if (userDto.getNickname().isBlank()) { + throw new NoSuchElementException("닉네임을 입력해 주세요."); + } + + if (userRepository.existsByUsername(userDto.getUsername())) { + throw new RuntimeException("아이디가 이미 존재합니다."); + } + if (userRepository.existsByNickname(userDto.getNickname())) { + throw new RuntimeException("닉네임이 이미 존재합니다."); + } + + User user = new User(); + user.setUsername(userDto.getUsername()); + user.setPassword(userDto.getPassword()); + user.setNickname(userDto.getNickname()); + userRepository.save(user); + + userDto.setUserId(user.getId()); + return userDto; + } + + public String login(UserDto userDto) { + User user = userRepository.findByUsername(userDto.getUsername()); + if (user != null && user.getPassword().equals(userDto.getPassword())) { + return user.getNickname() + " 님, 환영합니다!!"; + } + return "아이디 및 비밀번호가 일치하지 않습니다."; + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index 9b78d0c..0000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,15 +0,0 @@ -spring: - datasource: - url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 - username: your_username - password: your_password - driver-class-name: com.mysql.cj.jdbc.Driver - - jpa: - hibernate: - ddl-auto: create - show-sql: true - properties: - hibernate: - format_sql: true - dialect: org.hibernate.dialect.MySQL8Dialect \ No newline at end of file