Korea_sleep_Tech_springBoot/src/main/java/com/example/korea_sleepTech_springboot at main · seoyoonchoi/Korea_sleep_Tech_springB
Contribute to seoyoonchoi/Korea_sleep_Tech_springBoot development by creating an account on GitHub.
github.com
실제 코드를 더 확인하고 싶다면 위 링크를 통해서 확인할 수 있다.
📁 프로젝트 구성
com.example.korea_sleepTech_springboot
├── entity
│ ├── D_Post.java
│ └── D_Comment.java
├── dto
│ ├── request
│ │ ├── PostCreate/UpdateRequestDto.java
│ │ └── CommentCreate/UpdateRequestDto.java
│ └── response
│ ├── PostListResponseDto
│ ├── PostDetailResponseDto
│ ├── CommentResponseDto
│ └── PostWithCommentCountResponseDto
├── controller
│ ├── PostController
│ └── CommentController
├── service
│ ├── PostService / PostServiceImpl
│ └── CommentService / CommentServiceImpl
├── repository
│ ├── PostRepository
│ └── CommentRepository
└── common
└── ResponseDto / ApiMappingPattern
Entity 설계 - 양방향 관계의 구현
D_post(게시글)
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<D_Comment> comments = new ArrayList<>();
- mappedBy = "post": D_Comment 엔티티의 post 필드와 연결
- cascade = ALL: 게시글 삭제 시 댓글도 함께 삭제
- orphanRemoval = true: Post에서 댓글 객체를 제거하면, DB에서도 삭제됨
- fetch = LAZY: Post 조회 시 댓글을 즉시 불러오지 않고 필요 시 로딩
D_Comment (댓글)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private D_Post post;
- 여러 댓글이 하나의 게시글에 속하는 N:1 관계
- 외래키 post_id로 연결됨
- @ToString(exclude = "post"): 순환 참조 방지
연관관계 편의 메서드
public void addComment(D_Comment comment) {
this.comments.add(comment);
comment.setPost(this);
}
public void removeComment(D_Comment comment) {
this.comments.remove(comment);
comment.setPost(null);
}
- PA의 연관관계 주인은 @ManyToOne이 붙은 D_Comment 쪽
- 하지만 양쪽 모두 객체 그래프가 연결되어 있어야 영속성 컨텍스트가 동작함
DTO 설계
요청(Request)
- PostCreateRequestDto, PostUpdateRequestDto
- CommentCreateRequestDto, CommentUpdateRequestDto
> 모든 필드에 @NotBlank 또는 @Valid 지정 → 유효성 검증 적용
> Comment 작성 시 postId는 API URI에서 전달받음 (@PathVariable)
응답(Response)
- PostDetailResponseDto: 댓글 포함 전체 게시글 응답
- PostListResponseDto: 목록 조회 시 사용
- CommentResponseDto: 댓글 단건 응답
- PostWithCommentCountResponseDto: 댓글 수 통계 포함 게시글 응답
> CommentResponseDto는 Builder 패턴의 커스텀 생성 방식을 통해 유연성 확보
Controller 계층
PostController
- /api/v1/posts
- CRUD + 확장 기능 제공
// 댓글 포함 단건 조회
@GetMapping("/{id}")
public ResponseEntity<ResponseDto<PostDetailResponseDto>> getPostById(@PathVariable Long id)
// 댓글 수 기준 상위 5개 게시글
@GetMapping("/top-comments")
public ResponseEntity<ResponseDto<List<PostWithCommentCountResponseDto>>> getTop5PostsByComments()
📌 서비스 계층에서 List<Object[]>를 받아 직접 DTO 변환 → 유연한 통계 처리
CommentController
- /api/v1/comments
- 댓글 CUD 전용
- postId는 항상 URI로부터 전달
@PostMapping
public ResponseEntity<ResponseDto<CommentResponseDto>> createComment(@PathVariable Long postId, @RequestBody dto)
Service 계층
게시글 CRUD 핵심 흐름
- 생성(create): PostCreateRequestDto → D_Post → 저장 → DTO 변환
- 수정(update): 엔티티 조회 후 필드 변경 → save()
- 삭제(delete): 댓글 연관관계 먼저 해제 → deleteById()
댓글 처리 핵심 흐름
- 댓글 생성 시 post.addComment(comment) 호출
- 수정/삭제 시 postId와 commentId의 일치 여부를 검증
- 삭제 전 반드시 post.removeComment(comment) 호출 → orphanRemoval 발동
댓글 수 기반 통계 기능
List<Object[]> results = postRepository.findTop5ByOrderByCommentsSizeDesc();
- JPQL 또는 native SQL 결과가 Object[]로 반환됨
- 각 row를 PostWithCommentCountResponseDto로 변환
- ((Number) row[4]).intValue() 등 명시적 캐스팅 필수
'웹개발 > SpringBoot' 카테고리의 다른 글
| 보안 인증과 권한 시스템 - 2. Repository (2) | 2025.06.03 |
|---|---|
| 보안 인증과 권한 시스템 - 1. Entity (1) | 2025.06.02 |
| SpringBoot 검색기능+Enum활용 (0) | 2025.05.31 |
| Spring Boot + MySQL로 구현한 Student CRUD (1) | 2025.05.30 |
| Email 인증 구현 JavaMailSender 오류 해결 (0) | 2025.05.29 |