Skip to content

Commit

Permalink
feat: comment, post (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonbinn committed Dec 2, 2023
1 parent fb2eca3 commit ea0bf41
Show file tree
Hide file tree
Showing 14 changed files with 703 additions and 0 deletions.
20 changes: 20 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

//Querydsl 추가
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

// query 값 정렬
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0'

// Swagger
implementation 'org.springdoc:springdoc-openapi-ui:1.6.15'
implementation 'io.springfox:springfox-swagger2:2.9.2'
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
}

tasks.named('bootBuildImage') {
Expand All @@ -49,3 +63,9 @@ tasks.named('bootBuildImage') {
tasks.named('test') {
useJUnitPlatform()
}

// for queryDSL
clean {
delete file('src/main/generated')
}

2 changes: 2 additions & 0 deletions src/main/java/com/api/TaveShot/TaveShotApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
public class TaveShotApplication {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.api.TaveShot.domain.Comment.controller;

import com.api.TaveShot.domain.Comment.dto.CommentDto;
import com.api.TaveShot.domain.Comment.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequiredArgsConstructor
@RequestMapping("/api")
@RestController
public class CommentApiController {

private final CommentService commentService;

/* CREATE */
@PostMapping("/post/{id}/comments")
public ResponseEntity<Long> save(@PathVariable Long id, @RequestBody CommentDto.Request dto) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String gitIdAsString = authentication.getName();

Long gitId = Long.valueOf(gitIdAsString);
return ResponseEntity.ok(commentService.save(id, gitId, dto));
}

/* READ */
@GetMapping("/post/{id}/comments")
public List<CommentDto.Response> read(@PathVariable Long id) {
return commentService.findAll(id);
}

/* UPDATE */
@PutMapping({"/post/{postId}/comments/{id}"})
public ResponseEntity<Long> update(@PathVariable Long postId, @PathVariable Long id, @RequestBody CommentDto.Request dto) {
commentService.update(postId, id, dto);
return ResponseEntity.ok(id);
}

/* DELETE */
@DeleteMapping("/post/{postId}/comments/{id}")
public ResponseEntity<Long> delete(@PathVariable Long postId, @PathVariable Long id) {
commentService.delete(postId, id);
return ResponseEntity.ok(id);
}
}
59 changes: 59 additions & 0 deletions src/main/java/com/api/TaveShot/domain/Comment/domain/Comment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.api.TaveShot.domain.Comment.domain;

import com.api.TaveShot.domain.Member.domain.Member;
import com.api.TaveShot.domain.Post.domain.Post;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import java.util.List;

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Table(name = "comments")
@Entity
public class Comment {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(columnDefinition = "TEXT", nullable = false)
private String comment; // 댓글 내용

@Column(name = "created_date")
@CreatedDate
private String createdDate;

@Column(name = "modified_date")
@LastModifiedDate
private String modifiedDate;

@ManyToOne
@JoinColumn(name = "post_id")
private Post post;

@ManyToOne
@JoinColumn(name = "member_id")
private Member member; // 작성자

/*
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_comment_id")
private Comment parentComment; // 부모 댓글
@OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL)
private List<Comment> childComments; // 자식 댓글들
*/

/* 댓글 수정 */
public void update(String comment) {
this.comment = comment;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.api.TaveShot.domain.Comment.domain;

import com.api.TaveShot.domain.Post.domain.Post;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface CommentRepository extends JpaRepository<Comment,Long> {
/* 게시글 댓글 목록 가져오기 */
List<Comment> getCommentByPostOrderById(Post post);

Optional<Comment> findByPostIdAndId(Long postId, Long id);
}
68 changes: 68 additions & 0 deletions src/main/java/com/api/TaveShot/domain/Comment/dto/CommentDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.api.TaveShot.domain.Comment.dto;

import com.api.TaveShot.domain.Comment.domain.Comment;
import com.api.TaveShot.domain.Member.domain.Member;
import com.api.TaveShot.domain.Post.domain.Post;
import lombok.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class CommentDto {

/** 댓글 Service 요청을 위한 Request 클래스 **/

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class Request {
private Long id;
private String comment;
private String createdDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm"));
private String modifiedDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm"));
private Member member;
private Post post;


/* Dto -> Entity */
public Comment toEntity() {

return Comment.builder()
.id(id)
.comment(comment)
.createdDate(createdDate)
.modifiedDate(modifiedDate)
.member(member)
.post(post)
.build();
}
}


/** 댓글 정보를 리턴할 Response 클래스 **/
@RequiredArgsConstructor
@Getter
public static class Response {
private Long id;
private String comment;
private String createdDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm"));
private String modifiedDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm"));
private String gitName;
private Long memberId;
private Long postId;


/* Entity -> Dto*/
public Response(Comment comment) {
this.id = comment.getId();
this.comment = comment.getComment();
this.createdDate = comment.getCreatedDate();
this.modifiedDate = comment.getModifiedDate();
this.gitName = comment.getMember().getGitName();
this.memberId = comment.getMember().getId();
this.postId = comment.getPost().getId();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.api.TaveShot.domain.Comment.service;

import com.api.TaveShot.domain.Comment.domain.Comment;
import com.api.TaveShot.domain.Comment.domain.CommentRepository;
import com.api.TaveShot.domain.Comment.dto.CommentDto;
import com.api.TaveShot.domain.Member.domain.Member;
import com.api.TaveShot.domain.Member.repository.MemberRepository;
import com.api.TaveShot.domain.Post.domain.Post;
import com.api.TaveShot.domain.Post.domain.PostRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class CommentService {

private final CommentRepository commentRepository;
private final MemberRepository memberRepository;
private final PostRepository postRepository;

/* CREATE */
@Transactional
public Long save(Long id, Long gitId, CommentDto.Request dto) {
Optional<Member> member = memberRepository.findByGitId(gitId);
Post post = postRepository.findById(id).orElseThrow(() ->
new IllegalArgumentException("댓글 쓰기 실패: 해당 게시글이 존재하지 않습니다. " + id));

dto.setMember(member.orElse(null));
dto.setPost(post);

Comment comment = dto.toEntity();
commentRepository.save(comment);

return comment.getId();
}

/* READ */
@Transactional(readOnly = true)
public List<CommentDto.Response> findAll(Long id) {
Post post = postRepository.findById(id).orElseThrow(() ->
new IllegalArgumentException("해당 게시글이 존재하지 않습니다. id: " + id));
List<Comment> comments = post.getComments();
return comments.stream().map(CommentDto.Response::new).collect(Collectors.toList());
}

/* UPDATE */
@Transactional
public void update(Long postId, Long id, CommentDto.Request dto) {
Comment comment = commentRepository.findByPostIdAndId(postId, id).orElseThrow(() ->
new IllegalArgumentException("해당 댓글이 존재하지 않습니다. " + id));

comment.update(dto.getComment());
}

/* DELETE */
@Transactional
public void delete(Long postId, Long id) {
Comment comment = commentRepository.findByPostIdAndId(postId, id).orElseThrow(() ->
new IllegalArgumentException("해당 댓글이 존재하지 않습니다. id=" + id));

commentRepository.delete(comment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ public class Member extends BaseEntity {
private String profileImageUrl;

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.api.TaveShot.domain.Post.controller;

import com.api.TaveShot.domain.Post.dto.PostDto;
import com.api.TaveShot.domain.Post.service.PostService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;


/** REST API Controller **/
@RequestMapping("/api")
@RequiredArgsConstructor
@RestController
public class PostApiController {

private final PostService postService;

/* CREATE : 게시글을 현재 로그인한 사용자의 gitID를 가져와 관련된 정보로 저장 */
@PostMapping("/post")
public ResponseEntity<Long> save(@RequestBody PostDto.Request dto) {
SecurityContext securityContext = SecurityContextHolder.getContext();

Authentication authentication = securityContext.getAuthentication();
String gitIdAsString = authentication.getName();

Long gitId = Long.valueOf(gitIdAsString);

return ResponseEntity.ok(postService.save(dto, gitId));
}

/* READ */
@GetMapping("/post/{id}")
public ResponseEntity<PostDto.Response> read(@PathVariable Long id) {
PostDto.Response postResponse = postService.findById(id);
return ResponseEntity.ok(postResponse);
}

/* UPDATE */
@PutMapping("/post/{id}")
public ResponseEntity<Long> update(@PathVariable Long id, @RequestBody PostDto.Request dto) {
postService.update(id, dto);
return ResponseEntity.ok(id);
}

/* DELETE */
@DeleteMapping("/post/{id}")
public ResponseEntity<Long> delete(@PathVariable Long id) {
postService.delete(id);
return ResponseEntity.ok(id);
}

}
Loading

0 comments on commit ea0bf41

Please sign in to comment.