Skip to content

[게시판 + DB연동] 유소영 제출합니다.#39

Open
1028ragon wants to merge 13 commits into
1028ragonfrom
1028ragon-spring-db
Open

[게시판 + DB연동] 유소영 제출합니다.#39
1028ragon wants to merge 13 commits into
1028ragonfrom
1028ragon-spring-db

Conversation

@1028ragon

Copy link
Copy Markdown

과제명

게시판 + DB 연동

💡작업 내용

게시글 CRUD 기능 구현

  • 게시글 생성
  • 게시글 전체 조회
  • 게시글 단건 조회
  • 게시글 수정
  • 게시글 삭제

🔗참고 링크

  • 김영한 [온라인] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 — 스프링 MVC - 기본 기능, 스프링 MVC - 웹 페이지 만들기
  • 페이징 처리
  1. https://elevatingcodingclub.tistory.com/21
  2. https://kylo8.tistory.com/entry/Springboot-%EC%8A%A4%ED%94%84%EB%A7%81-JPA%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%ED%8E%98%EC%9D%B4%EC%A7%95-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-PageableDefault-pageable#google_vignette

🤔 느낀 점 / 어려웠던 점

  • 스프링에 좀 더 익숙해졌던 기회가 된 것 같습니다.
  • MVC패턴과 DTO의 활용을 더 잘 이해하게 되었습니다.

@1028ragon 1028ragon self-assigned this May 29, 2026
@1028ragon 1028ragon linked an issue May 29, 2026 that may be closed by this pull request
8 tasks

@Donghwan814 Donghwan814 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

안녕하세요 소영님!
우선 이번 주차 과제 제출하시느라 고생 많으셨습니다!

이번 과제는 저번 주 과제와 크게 다르지 않은 부분이 많았고, 코드도 전반적으로 잘 작성해주셔서 이번에는 코드 자체의 수정 사항보다는 왜 이렇게 작성했는지, 어떤 의도로 사용했는지에 대한 질문 위주로 피드백을 남겼습니다.

이번 주차는 특히 DB 연동이 중요한 부분이라고 생각됩니다.
다만 제출해주신 이미지를 확인해보니 현재는 Postman으로 API 테스트한 결과만 첨부되어 있는 것 같습니다.

MySQL과 연동해서 작업해주신 만큼, 실제로 게시글 생성, 조회, 수정, 삭제가 MySQL DB에 정상적으로 반영되는지도 함께 확인할 수 있도록 DB 조회 결과 화면도 같이 첨부해주시면 더 좋을 것 같습니다!


return ResponseEntity.ok(postService.getAllPosts());
public ResponseEntity<PostPageResponse> getAllPosts(
@PageableDefault(size = 10, sort = "id", direction = Sort.Direction.DESC)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@PageableDefault를 사용해서 id 기준 내림차순으로 10개씩 조회되도록 설정해주신 부분 좋았습니다!

추가로 게시글 조회 시 항상 id 기준으로만 정렬하는 것이 아니라, 상황에 따라 생성일 기준이나 조회수 기준으로 정렬이 필요할 수도 있을 것 같습니다. 이런 경우에는 어떤 방식으로 작성해볼 수 있을까요?

그리고 코드를 살펴보니 반환 타입으로 List posts를 사용해주셨는데, 페이지네이션을 적용하는 상황에서 List<>를 사용하신 이유에 대한 소영님의 생각도 궁금합니다.

페이지네이션에서는 Page, Slice 같은 방식도 존재합니다! 이 부분들도 한 번 학습해 보시는 것을 권장드립니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Q1. 게시글 조회 시 정렬 기준 관련
A1. 현재 코드에서는 Pageable을 사용하고 있기 때문에 sort 파라미터를 활용하여 정렬 기준을 변경하면 된다고 생각합니다. 찾아본 결과 만약 나중에 여러 기본 정렬 조건이 필요해진다면 @SortDefault 어노테이션을 활용해 볼 수 있다고 생각합니다!

Q2. 페이지네이션을 적용하는 상황에서 List<>를 사용한 이유에 대해
A1.
당시에는 DTO를 활용하여 응답 데이터를 직접 관리하는 방향으로만 생각했기 때문에 List와 PostPageResponse를 사용했습니다.
리뷰를 통해 Page를 직접 반환하는 방식도 가능하며, 현재 구조보다 더 간결하게 구현할 수 있다는 점을 알게 되었습니다! 이 부분 학습하여 코드에 반영해보겠습니다!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

지난주에 피드백 드렸던 record 방식을 잘 적용해주신 점 좋았습니다!

다만 한 가지 궁금한 부분은 ErrorResponse 파일을 따로 만들어주셨는데, 현재 구조에서는 message만 전달하고 있는 것으로 보입니다. 이 경우 어떤 예외가 발생했는지는 알 수 있지만, 클라이언트 입장에서는 해당 에러가 어떤 상태 코드와 연결되는지 바로 파악하기는 조금 어려울 수도 있을 것 같습니다.

그래서 message와 함께 status 값도 같이 담아주면 에러 응답의 의미가 더 명확해질 것 같습니다.

이 부분도 한 번 고려해보시면 좋을 것 같습니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

넵 피드백 감사합니다! 상태값도 같이 반환해주는걸로 리펙토링 해보겠습니다!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

한 가지 궁금한 부분은 boolean first 필드입니다. 현재 응답에 page 값이 함께 포함되어 있기 때문에, page == 0 조건으로도 첫 번째 페이지인지 판단할 수 있을 것 같습니다.

혹시 page 값으로 판단하지 않고 first 값을 별도로 내려주신 이유가 있을까요?

@1028ragon 1028ragon Jun 4, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

피드백 감사합니다.
처음에는 클라이언트가 사용할 수 있는 페이지 관련 정보가 많을수록 좋다고 생각해서 Page 객체에서 제공하는 isFirst() 값도 함께 내려주었습니다.
하지만 말씀해주신 것처럼 현재 응답에는 page 값이 포함되어 있고, page == 0 조건으로 첫 번째 페이지 여부를 판단할 수 있습니다. 중복 정보라고 판단되어 앞으로는 API응답에 필요한 값만 명확하게 담아 보겠습니다!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Post 엔티티를 깔끔하게 작성해주셔서 현재 구조에서는 크게 수정할 부분은 없어 보입니다!

지금은 엔티티가 Post 하나뿐이라 id, createdAt을 엔티티 안에 직접 작성해도 괜찮다고 생각합니다.

다만 추후에 엔티티가 많아지면 여러 엔티티에서 공통으로 사용되는 필드들이 생길 수 있을 것 같습니다. 예를 들어 id, 생성일시, 수정일시, 삭제일시 같은 값들은 대부분의 엔티티에서 반복될 가능성이 높습니다.

이런 경우에는 BaseEntity와 같은 공통 엔티티 클래스로 분리해서 관리하는 방식도 많이 사용하는 것으로 알고 있습니다.

공통 필드를 한 곳에서 관리하면 코드 중복을 줄이고, 추후 유지보수할 때도 더 편리할 것 같아서 이 부분도 한 번 학습해보시면 좋을 것 같습니다!

참고 자료

https://blogan99.tistory.com/145

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

피드백과 참고 자료 감사합니다! BaseEntity와 같은 공통 엔티티 클래스를 만들어 관리하는 방식도 학습하여 코드에 반영해보겠습니다!

Comment on lines +94 to +95
if (postRepository.existsByTitle(request.title())) {
throw new DuplicateTitleException();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

수정 시 제목 중복을 확인해주는 예외 처리 로직을 추가해주신 부분 좋았습니다!

다만 이 부분에서 한 가지 궁금한 점이 있습니다.

현재 코드는 수정 요청이 들어왔을 때 바로 existsByTitle(request.title())로 제목 중복 여부를 확인하고 있는데, 만약 사용자가 제목은 변경하지 않고 내용만 수정하는 경우에는 기존 게시글의 제목과 동일하기 때문에 중복 예외가 발생할 수도 있을 것 같습니다.

이런 상황은 어떻게 처리하면 좋을지 궁금합니다!

@1028ragon 1028ragon Jun 1, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

피드백 감사드립니다!
생각해본 결과
1.

if (postRepository.existsByTitle(request.title())
        && !post.getTitle().equals(request.title())) {
    throw new DuplicateTitleException();
}

이렇게 조건을 추가로 붙이면 내용만 수정하는 경우에는 정상적으로 수정할 수 있고, 다른 게시글의 제목과 중복되는 경우에만 예외가 발생하도록 처리할 수 있을 것 같습니다.

추가로 if문 조건 추가를 통한 중복 검사뿐만 아니라, 엔티티의 title에 @column(unique = true) 제약조건을 추가하는 방향도 고려해 볼 수 있을 것 같습니다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

환경변수를 활용해서 DB 접속 정보를 분리해주신 부분 좋았습니다!

DATABASE_URL, DATABASE_USERNAME, DATABASE_PASSWORD처럼 민감한 정보들을 직접 코드에 작성하지 않고 외부 환경변수로 관리하도록 설정해주신 점이 좋았습니다.

.gitignore도 확인해봤을 때 .env 파일을 통해 민감한 정보를 따로 관리하고 계신 것으로 보여서, 보안 측면에서도 잘 적용해주신 것 같습니다.

@leesj0706

Copy link
Copy Markdown

안녕하세요 소영님! 이번 주차는 지난 과제에 DB 연동이 추가된 형태인데요. 지난주 리뷰에서 함께 이야기 나누었던 코드 개선 포인트들을 어떻게 고민하고 적용해 보셨는지 중심적으로 여쭤보고자 합니다! 편하게 답변해 주세요.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

포스트맨 캡처 화면을 보니 게시글 삭제 성공 시 반환값으로 1이 찍히는 것 같습니다! 물론 이렇게 처리해도 기능상 문제는 없지만, "삭제되었습니다"와 같은 명확한 메시지나 성공 상태를 함께 내려주면 클라이언트 입장에서 훨씬 직관적일 것 같아요. API 공통 응답 포맷을 어떻게 구성하면 더 보기 좋을지 한 번 고민해 보시고 적용해 보시면 좋겠습니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

좋은 피드백 감사합니다! 단순히 상태코드만 반환하는게 아니라 공통 응답 DTO를 두고 status, message 형태로 관리하는 방법도 고려해보겠습니다!


# JPA Settings
# JPA + Hibernate Settings
spring.jpa.hibernate.ddl-auto=update

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

JPA 설정에서 ddl-auto 설정을 update로 지정해 주셨네요! 혹시 특별히 update 설정을 선택하신 이유나 의도가 있으신지 궁금합니다!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

JPA를 학습하면서 엔티티를 수정하면서 테이블 구조를 자동으로 반영하기 위해 사용했습니다. 그냥 단순히 개발 시엔 update 설정을 한다 라고만 알고있어서 문제점을 인지하지 못했는데, 이번에 다시 찾아보면서 update 옵션은 학습이나 개발 환경에서는 편리하지만, 실무에서는 의도하지 않은 스키마 변경이 발생할 수 있어 validate나 별도의 도구를 사용하는 경우가 많다는 점도 알게 되었습니다. 앞으로 이 부분도 신경쓰겠습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 유소영 10주차 과제 - 게시판 + DB연동

3 participants