diff --git a/.gitignore b/.gitignore index c2065bc..4c75e42 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ out/ ### VS Code ### .vscode/ + +.env \ No newline at end of file diff --git a/README.md b/README.md index 395edc5..d8ca717 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ # backend-study-sns +강지원 diff --git a/build.gradle b/build.gradle index 610d6a6..cf03320 100644 --- a/build.gradle +++ b/build.gradle @@ -19,11 +19,27 @@ repositories { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'com.mysql:mysql-connector-j:9.0.0' + implementation 'me.paulschwarz:spring-dotenv:4.0.0' + + testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + // lombok + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' } +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} tasks.named('test') { useJUnitPlatform() } diff --git a/src/main/java/com/example/devSns/controller/CommentController.java b/src/main/java/com/example/devSns/controller/CommentController.java new file mode 100644 index 0000000..a040745 --- /dev/null +++ b/src/main/java/com/example/devSns/controller/CommentController.java @@ -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 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); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/controller/PostController.java b/src/main/java/com/example/devSns/controller/PostController.java new file mode 100644 index 0000000..1a2a41f --- /dev/null +++ b/src/main/java/com/example/devSns/controller/PostController.java @@ -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 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); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/entity/Comment.java b/src/main/java/com/example/devSns/entity/Comment.java new file mode 100644 index 0000000..4eb30dc --- /dev/null +++ b/src/main/java/com/example/devSns/entity/Comment.java @@ -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") + @JsonBackReference + private Post post; + + @PrePersist + public void onCreate(){ + createdAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/entity/Post.java b/src/main/java/com/example/devSns/entity/Post.java new file mode 100644 index 0000000..143a980 --- /dev/null +++ b/src/main/java/com/example/devSns/entity/Post.java @@ -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 +@NoArgsConstructor +@AllArgsConstructor +@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 comments = new ArrayList<>(); + @PrePersist + public void onCreate(){ + createdAt = LocalDateTime.now(); + updatedAt = LocalDateTime.now(); + } + + @PreUpdate + public void onUpdate(){ + updatedAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/repository/CommentRepository.java b/src/main/java/com/example/devSns/repository/CommentRepository.java new file mode 100644 index 0000000..c293959 --- /dev/null +++ b/src/main/java/com/example/devSns/repository/CommentRepository.java @@ -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 { + List findByPost_Id(Long postId); +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/repository/PostRepository.java b/src/main/java/com/example/devSns/repository/PostRepository.java new file mode 100644 index 0000000..4fd8426 --- /dev/null +++ b/src/main/java/com/example/devSns/repository/PostRepository.java @@ -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 {} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/service/CommentService.java b/src/main/java/com/example/devSns/service/CommentService.java new file mode 100644 index 0000000..c2e8157 --- /dev/null +++ b/src/main/java/com/example/devSns/service/CommentService.java @@ -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 getCommentByPost(Long postId){ + return commentRepository.findByPost_Id(postId); + } + + 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); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/service/PostService.java b/src/main/java/com/example/devSns/service/PostService.java new file mode 100644 index 0000000..e9dce8b --- /dev/null +++ b/src/main/java/com/example/devSns/service/PostService.java @@ -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 findAll(){ + return postRepository.findAll(); + } + + public Optional findById(Long id){ + return postRepository.findById(id); + } + + 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()); + + updatedPost.setId(id); + + return postRepository.save(updatedPost); + } + + public void delete(Long id){ + postRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f3f10af..f3fabed 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -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 \ No newline at end of file