Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b1dbd49
Controller, Service, Repository 기초 작업 완료
scholar-star Oct 6, 2025
1e63d38
CRUD 기능 구현 완료
scholar-star Oct 8, 2025
43cb730
EntityNotFoundException handler 추가, findByName 수정
scholar-star Oct 8, 2025
299dc06
DataAccessException(SQL) 관련 handler 추가
scholar-star Oct 8, 2025
ac326f8
update/delete의 Postbody로 id를 포함하여 보내던 부분을 @PathVariable로 리팩토링
scholar-star Oct 10, 2025
a24b3aa
기존 수정사항 반영, Entity와 Controller, Service 토대 만들기
scholar-star Nov 1, 2025
676e68d
Controller와 Service get, create 진행, Entity에 Join 연결
scholar-star Nov 1, 2025
7b94fda
Controller와 Service get, create 진행, Entity에 Join 연결
scholar-star Nov 1, 2025
7b53c52
User Entity 추가, Reply에 Post와 User의 의존 관계 연결
scholar-star Nov 2, 2025
90ce723
service, controller 토대 만들기
scholar-star Nov 2, 2025
3df566e
GlobalExceptionHandler로 예외 처리 옮기기, Controller 기본 채워넣기
scholar-star Nov 3, 2025
7fe66e9
ReplyRepository findby 형태 변경(postId->Posts), 오류 해결
scholar-star Nov 4, 2025
5f6e179
Post 리팩토링
scholar-star Nov 4, 2025
bb8aaf7
Post, Reply Like 추가
scholar-star Nov 9, 2025
0ba9159
좋아요 기능 추가 Test 완료
scholar-star Nov 11, 2025
6bb6db2
좋아요 기능 추가 Test
scholar-star Nov 11, 2025
39a61b6
Revert "좋아요 기능 추가 Test"
scholar-star Nov 11, 2025
e52f1a2
수정사항 반영 첫 번째
scholar-star Nov 12, 2025
b759e4b
수정사항 반영 두 번째
scholar-star Nov 13, 2025
3042d2a
Post 검색 기능 추가
scholar-star Nov 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ repositories {

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
}

tasks.named('test') {
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/example/devSns/DevSnsApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@

@SpringBootApplication
public class DevSnsApplication {

public static void main(String[] args) {
SpringApplication.run(DevSnsApplication.class, args);
}

}
}
59 changes: 59 additions & 0 deletions src/main/java/com/example/devSns/controllers/PostController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.example.devSns.controllers;

import com.example.devSns.dto.PostDTO;
import com.example.devSns.dto.PostResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.example.devSns.services.PostService;
import java.util.List;

@RestController
@RequestMapping("/sns")
@RequiredArgsConstructor
public class PostController {
private final PostService postService;

@GetMapping("/show")
public ResponseEntity<List<PostResponse>> showPosts() {
List<PostResponse> posts = postService.findAll();
return new ResponseEntity<>(posts, HttpStatus.OK);
}

@GetMapping("/show/{userID}")
public ResponseEntity<List<PostResponse>> showPost(@PathVariable Long userID) {
List<PostResponse> post = postService.findByUserID(userID);
return new ResponseEntity<>(post, HttpStatus.OK);
}

@GetMapping("/show/{content}")
public ResponseEntity<List<PostResponse>> showPost(@PathVariable String content) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메소드의 이름을 searchPostByKeyword 와같이 명확하게 한다면, 추후에 코드를 수정해야하는 경우에 메소드명만 보고도 기능을 유추할 수 있어 더 좋을 것 같아요! (service쪽도 마찬가지!!)

List<PostResponse> post = postService.findByContent(content);
return new ResponseEntity<>(post, HttpStatus.OK);
}

@PostMapping("/add")
public ResponseEntity<PostResponse> addPost(@RequestBody PostDTO postDTO) {
PostResponse postResponse = postService.save(postDTO);
return new ResponseEntity<>(postResponse, HttpStatus.CREATED);
}

@PutMapping("/{id}")
public ResponseEntity<PostResponse> updatePost(@PathVariable Long id, @RequestBody PostDTO postDTO) {
PostResponse postResponse = postService.update(id, postDTO);
return new ResponseEntity<>(postResponse, HttpStatus.OK);
}

@PatchMapping("/{id}/likeit")
public ResponseEntity<PostResponse> likePost(@PathVariable Long id) {
PostResponse postResponse = postService.likePost(id);
return new ResponseEntity<>(postResponse, HttpStatus.OK);
}

@DeleteMapping("/{id}")
public ResponseEntity<String> deletePost(@PathVariable Long id) {
postService.delete(id);
return new ResponseEntity<>("Post deleted", HttpStatus.OK);
}
}
53 changes: 53 additions & 0 deletions src/main/java/com/example/devSns/controllers/ReplyController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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("/sns/reply")
@RequiredArgsConstructor
public class ReplyController {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reply라면 답글을 의미하는 것 같다고 생각했는데, 그렇다면 댓글과 답글을 따로 관리하는 방식인가요?

private final ReplyService replyService;

@GetMapping("/{postId}/replies")
public ResponseEntity<List<ReplyResponse>> getReplies(@PathVariable long postId) {
List<ReplyResponse> replies = replyService.replyGetAll(postId);
ResponseEntity<List<ReplyResponse>> responseEntity = new ResponseEntity<>(replies, HttpStatus.OK);
return responseEntity;
}

@PostMapping("/{postId}/add")
public ResponseEntity<ReplyResponse> writeReply(@PathVariable long postId, @RequestBody ReplyDTO reply) {
ReplyResponse replyResponse = replyService.writeReply(postId, reply);
ResponseEntity<ReplyResponse> responseEntity = new ResponseEntity<>(replyResponse, HttpStatus.OK);
return responseEntity;
}

@PutMapping("/{replyId}")
public ResponseEntity<ReplyResponse> updateReply(@PathVariable long replyId, @RequestBody ReplyDTO reply) {
ReplyResponse replyResponse = replyService.updateReply(replyId, reply);
ResponseEntity<ReplyResponse> responseEntity = new ResponseEntity<>(replyResponse, HttpStatus.OK);
return responseEntity;
}

@PatchMapping("/{id}")
public ResponseEntity<ReplyResponse> likeReply(@PathVariable long id) {
ReplyResponse replyResponse = replyService.likeReply(id);
ResponseEntity<ReplyResponse> responseEntity = new ResponseEntity<>(replyResponse, HttpStatus.OK);
return responseEntity;
}

@DeleteMapping("/{replyId}")
public ResponseEntity<String> deleteReply(@PathVariable long replyId) {
String deleteCheck = replyService.deleteReply(replyId);
ResponseEntity<String> responseEntity = new ResponseEntity<>(deleteCheck, HttpStatus.OK);
return responseEntity;
}
}
22 changes: 22 additions & 0 deletions src/main/java/com/example/devSns/dto/PostDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.devSns.dto;

import com.example.devSns.entities.Posts;
import com.example.devSns.entities.Users;
import jakarta.validation.constraints.NotBlank;

import java.time.LocalDateTime;

public record PostDTO(
@NotBlank Long userId,
@NotBlank String username,
String content
) {
public static Posts dtoToEntity(PostDTO postDTO, Users user) {
Posts postEntity = Posts.builder()
.users(user)
.content(postDTO.content())
.createat(LocalDateTime.now())
.build();
return postEntity;
}
}
27 changes: 27 additions & 0 deletions src/main/java/com/example/devSns/dto/PostResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.devSns.dto;

import com.example.devSns.entities.Posts;
import lombok.*;

import java.time.LocalDateTime;

@Builder
public record PostResponse(
Long id,
String username,
String content,
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();
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/example/devSns/dto/ReplyDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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.time.LocalDateTime;

public record ReplyDTO(
Long userID,
String comment
) {
public static Replies dtoToEntity(Posts post, Users user, ReplyDTO replyDTO) {
return Replies.builder()
.posts(post)
.users(user)
.createAt(LocalDateTime.now())
.reply(replyDTO.comment())
.build();
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/example/devSns/dto/ReplyResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.devSns.dto;

import com.example.devSns.entities.Replies;
import lombok.Builder;

@Builder
public record ReplyResponse(
long replyId,
String username,
String comment,
Integer like
) {
public static ReplyResponse entityToDTO(Replies replies) {
return ReplyResponse.builder()
.replyId(replies.getId())
.username(replies.getUsers().getUsername())
.comment(replies.getReply())
.like(replies.getLikeit())
.build();
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/example/devSns/entities/Posts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.example.devSns.entities;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;

import java.time.LocalDateTime;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Posts {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@NotNull
@Column
private String content;

@JoinColumn(name = "users_id")
@ManyToOne
@NotNull
private Users users;

@ColumnDefault("0")
private int likeit;

@Column
private LocalDateTime createat;

@Column
private LocalDateTime updateat;

public void setUpdateat(LocalDateTime updateat) {
this.updateat = updateat;
}

public void setContent(String content) {
this.content = content;
}

public void setLikeit(int likeit) {
this.likeit = likeit;
}
}
52 changes: 52 additions & 0 deletions src/main/java/com/example/devSns/entities/Replies.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.example.devSns.entities;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
import java.time.LocalDateTime;

@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;

@Column
@ColumnDefault("0") // Table 생성 시점 기본값
private int likeit;

@NotNull
private String reply;

@NotNull
private LocalDateTime createAt;

private LocalDateTime updateAt;

public void setReply(String reply) {
this.reply = reply;
}

public void setUpdateAt(LocalDateTime updateAt) {
this.updateAt = updateAt;
}

public void setLikeit(int likeit) {
this.likeit = likeit;
}
}
29 changes: 29 additions & 0 deletions src/main/java/com/example/devSns/entities/Users.java
Original file line number Diff line number Diff line change
@@ -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.time.LocalDate;

@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 LocalDate birthday;
}
15 changes: 15 additions & 0 deletions src/main/java/com/example/devSns/repositories/PostRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.devSns.repositories;

import com.example.devSns.entities.Posts;
import com.example.devSns.entities.Users;
import org.springframework.data.jpa.repository.JpaRepository;

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

public interface PostRepository extends JpaRepository<Posts, Long> {
public List<Posts> findAll();
public Optional<Posts> findById(Integer id);
public List<Posts> findByUsers(Users user);
public List<Posts> findByContentContaining(String partialContent);
}
12 changes: 12 additions & 0 deletions src/main/java/com/example/devSns/repositories/ReplyRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
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<Replies, Long> {
public List<Replies> findByPosts(Posts posts);
public Replies findById(long id);
}
Loading