Skip to content

Feat/week 1#2

Open
junyi04 wants to merge 14 commits intoApptiveDev:강준이from
junyi04:feat/week-1
Open

Feat/week 1#2
junyi04 wants to merge 14 commits intoApptiveDev:강준이from
junyi04:feat/week-1

Conversation

@junyi04
Copy link
Copy Markdown

@junyi04 junyi04 commented Oct 7, 2025

과제 1

게시글 CRUD 구현하기

Copy link
Copy Markdown
Contributor

@sinsehwan sinsehwan left a comment

Choose a reason for hiding this comment

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

빠른 시간 내에 되게 잘 구현해주셨네요! 고생하셨습니다. 동작도 잘 되네요
image
입력 값 검증이나 DB 제약조건, 테스트 코드 등 추가되면 더 좋은데, 이건 천천히 도입해보시면 될 것 같습니다. 수고하셨습니다.

Comment on lines +21 to +25
@GetMapping
public String list(Model model) {
model.addAttribute("posts", postService.getAllPosts());
return "list";
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SSR 방식을 사용하셨네요! 저도 서버 단에서 view까지 다룰 수 있다는 점에서 SSR을 선호합니다. CSR방식과 SSR방식의 장단점이 무엇일까요?

Copy link
Copy Markdown
Author

@junyi04 junyi04 Oct 10, 2025

Choose a reason for hiding this comment

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

SSR 방식

사용자가 웹페이지를 요청했을 때,
서버에 필요한 데이터와 HTML을 모두 합쳐서 완성된 페이지를 만들어 서용자게에 제공

pros

  • 빠른 초기 로딩 속도
    완성된 형태의 페이지를 빠르게 받기 가능
  • 검색 엔진 최적화
    검색 엔진이 HTML 쉽게 분석하고 파악 가능

cons

  • 서버 부하 증가
    서버가 일일이 페이지를 민들어야 함
  • 페이지 이동 시 blinking
    페이지 이동 때마다 전체 페이지를 서버로부터 다시 받아오기 때문에 화면이 깜빡일 수 있음

CSR 방식

사용자가 웹페이지를 요청했을 때,
서버는 아주 기본적인 HTML 뼈대와 javascript 파일만 보내줌.
사용자의 웹 브라우저는 그 javascript를 실행해서 데이터를 서버에 다시 요청하고 데이터를 받아 동적으로 페이지를 완성

pros

  • 초기 로딩 후 빠른 인터렉션
    한 번 페이지 받아오면 부분적 업데이트
  • 서버 부하 감소
    서버는 데이터 제공하는 역할에만 집중, 화면을 그리는 일은 브라우저가 담당

cons

  • 느린 초기 로딩 속도
    처음에 javascript 파일과 데이터를 모두 다운로드
  • 검색 엔진 최적화의 어려움
    초기에 내용이 거의 없는 HTML을 받아 검색 엔진이 분석하고 파악하기에 어려움

Code Review SSR

  • postService.getAllPosts()
    서버에서 미리 모든 게시물 데이터를 가져와

  • model.addAttribute(...)
    이 데이터를 list라는 이름의 View(HTML)에 전달

완성된 list 페이지를 사용자에게 반환

Comment on lines +4 to +8

분리해서 사용하는 이유
- Entity 객체의 변경을 피하기 위함
- 클라이언트와 통신하는 ResponseDTO나 RequestDTO는 요구사항에 따라 자주 변경
- 어떤 요청에서는 특정 값이 추가되거나 없을 수 있어서 분리해서 관리 No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

내용 정리 좋습니다! entity랑 dto를 분리하는 이유를 한 가지 더 설명드리면, entity는 DB의 table을 정의하는 일종의 스키마 역할을 하게 됩니다. 따라서 table 정의 및 매핑 관련된 설정은 entity에 두고, 외부 입력 값 검증이나 변환은 DTO에서 책임지도록 하는 것이 책임 분리 관점에서 더 적절합니다.

Comment on lines +18 to +23
private String title;
private String content;
private String author;

private LocalDateTime createdAt;
private LocalDateTime updatedAt;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

entity에서 DB 스키마 관련 제약조건을 추가해서 더 안전하게 구성할 수 있습니다!

null 값이 들어가면 안 되는 속성에 @Column(nullable = false)을 추가하면 의도치 않게 DB에 null값이 들어가는 것을 원천적으로 차단할 수 있습니다.

// e.g.
@Column(nullable = false, length = 255)
private String title;

@@ -0,0 +1,22 @@
데이터베이스와 직접적으로 맞닿는 핵심적인 클래스
- entity를 기준으로 테이블 생성
- Builder 패턴을 사용해서 필요한 값만 넣음
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Builder 패턴의 경우 호불호가 갈리는 편입니다. Builder를 쓰면 선택적으로 필드를 구성할 수 있다는 장점이 있지만, 컴파일 때 필수 필드에 모두 유효한 값이 들어갔는지 체크하기 어렵다는 단점도 있습니다. 이 점 고려하셔서 사용하시면 될 것 같습니다!

Comment on lines +11 to +31
@Transactional(readOnly = true)
public class PostService {
private final PostRepository postRepository;

// 생성자
public PostService(PostRepository postRepository) {
this.postRepository = postRepository;
}

public List<PostEntity> getAllPosts() {
return postRepository.findAll();
}

public PostEntity getPost(Long id) {
return postRepository.findById(id).orElseThrow();
}

@Transactional
public PostEntity createPost(PostEntity postEntity) {
return postRepository.save(postEntity);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Transactional(readOnly = true), @Transactional 분리해서 잘 적용해주셨네요!

Comment on lines +27 to +29
save
- 새 엔터티 저장
- id가 없으면 persist, 있으면 merge
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

오.. 혹시 영속성 계층, 1차 캐시 등 JPA 관련해서 따로 공부하신 적이 있으신가요?

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.

과제 하면서 사용한 레퍼런스를 통해 해당 기능을 알게 됐습니다. 스프링부트에 대한 지식이 아직 부족해서 더 공부해보겠습니다!

tomchaccom added a commit that referenced this pull request Nov 11, 2025
* Update README.md

* feat(comment) : 댓글 API 개발 완료

* chore(gradle) : lombok,h2 의존성 추가

* chore(gradle) : JPA 의존성 추가

* feat(entity) : 게시글 엔티티 설계

* chore(gradle) : JPA -> JDBC 의존성 추가 및 삭제

* fix(entity) : JPA 어노테이션 제거

* chore(entity): 엔티티 좋아요 수 필드명 수정

* feat(repo) : JDBC Template를 통해서 CRUD 구현

* feat(service) : 서비스 계층 개발
- 기존 repo가 findById 시에 int를 인자로 받아 Long으로 수정

* style(entity) : 가독성 향상을 위한 띄어쓰기

* feat(controller) : CRUD API 설계 완료

* feat(h2): h2 설정, 스키마 sql로 작성
- h2 url, 사용자 작성
- JPA와 다르게 JDBC는 직접 DDL을 작성

* style(sql) : 들여쓰기

* feat(exception) : 사용자 정의 예외 추가,

* feat(Post) : 게시판 작성 로직 생성, DTO 및 API 정의

* feat(Get) : 게시물 단일 조회, 모든 게시글 조회 로직 생성, DTO 및 API 정의

* feat(Get) : 게시물 수정 로직 생성, DTO 및 API 정의

* feat(update) : 게시물 수정 로직 생성, DTO 및 API 정의

* chore(import) : 의존성 추가

* fix(save) : SQL 오류 수정 및 수정 시간 오류 해결

* chore: 카멜케이스 적용

* chore : 카멜 케이스 적용

* fix(JPA) : JDBC에서 JPA로 패러다임 변경
- jpa 의존성 추가
- SQL 로 처리하던 로직을 jpa를 통해 처리

* feat: 댓글 엔티티 추가

* feat: 엔티티 연관관계 매핑
- 게시글 : 댓글 일대다
- 대댓글(댓글에 댓글 추가) 일대다

* feat: 엔티티, 컨트롤러, 서비스, 리포지터리 생성

* feat(dto) : 댓글 수정 및 생성용 Dto 와 메소드 개발

* feat(CRUD) : 댓글 CRUD 로직 개발

* feat(comment) : 댓글 생성 API 개발 완료
- Dto 엔티티 변환 로직을 통해서 댓글에 post 값 할당

* feat(comment) : 댓글 조회, 수정, 삭제 구현
- 조회시에는 연관된 게시물에 댓글을 조회하도록 설정
- 수정, 삭제 URL은 조금더 고민해보기

* feat(reply) : 대댓글 작성 로직 및 API 개발

* fix(comment) : 댓글 조회 API 오류 해결
- 댓글 조회시, 같은 게시글에 달린 대댓글이 중복으로 조회되는 문제 해결
- 댓글 중 parent(부모댓글) 이 null 값인 것들만 조회하도록 수정

* chore : 사용하지 않는 병수 및 의존성 제거

* fix(post) : 게시글 조회 API 오류 해결
- 게시글도 댓글과 마찬가지로 조회시, 같은 게시글에 달린 대댓글이 중복으로 조회되는 문제 해결
- 댓글 중 parent(부모댓글) 이 null 값인 것들만 조회하는 메소드를 게시글 service에도 적용

* chore: 사용되지 않는 메소드 리턴 제거

* chore : validation 의존성 추가

* feat : Dto 에 validation 추가

* feat: 댓글 API,유효성 검증 실패시 예외처리 추가
- validation 실패시 발생하는 MethodArgumentNotValidException은 try-catch로는 잡히지 않아, 전역 핸들러 추가

* chore: 미사용 메소드 삭제

* chore: import 정리

* chore: 경고 제거

---------

Co-authored-by: tomchccom <dreamkms2014@gmail.com>

* feat(test):  게시글 단위, 통합 테스트 구현 (#2)

* chore(gradle) : lombok,h2 의존성 추가

* chore(gradle) : JPA 의존성 추가

* feat(entity) : 게시글 엔티티 설계

* chore(gradle) : JPA -> JDBC 의존성 추가 및 삭제

* fix(entity) : JPA 어노테이션 제거

* chore(entity): 엔티티 좋아요 수 필드명 수정

* feat(repo) : JDBC Template를 통해서 CRUD 구현

* feat(service) : 서비스 계층 개발
- 기존 repo가 findById 시에 int를 인자로 받아 Long으로 수정

* style(entity) : 가독성 향상을 위한 띄어쓰기

* feat(controller) : CRUD API 설계 완료

* feat(h2): h2 설정, 스키마 sql로 작성
- h2 url, 사용자 작성
- JPA와 다르게 JDBC는 직접 DDL을 작성

* style(sql) : 들여쓰기

* feat(exception) : 사용자 정의 예외 추가,

* feat(Post) : 게시판 작성 로직 생성, DTO 및 API 정의

* feat(Get) : 게시물 단일 조회, 모든 게시글 조회 로직 생성, DTO 및 API 정의

* feat(Get) : 게시물 수정 로직 생성, DTO 및 API 정의

* feat(update) : 게시물 수정 로직 생성, DTO 및 API 정의

* chore(import) : 의존성 추가

* fix(save) : SQL 오류 수정 및 수정 시간 오류 해결

* chore: 카멜케이스 적용

* chore : 카멜 케이스 적용

* fix(JPA) : JDBC에서 JPA로 패러다임 변경
- jpa 의존성 추가
- SQL 로 처리하던 로직을 jpa를 통해 처리

* feat: 댓글 엔티티 추가

* feat: 엔티티 연관관계 매핑
- 게시글 : 댓글 일대다
- 대댓글(댓글에 댓글 추가) 일대다

* feat: 엔티티, 컨트롤러, 서비스, 리포지터리 생성

* feat(dto) : 댓글 수정 및 생성용 Dto 와 메소드 개발

* feat(CRUD) : 댓글 CRUD 로직 개발

* feat(comment) : 댓글 생성 API 개발 완료
- Dto 엔티티 변환 로직을 통해서 댓글에 post 값 할당

* feat(comment) : 댓글 조회, 수정, 삭제 구현
- 조회시에는 연관된 게시물에 댓글을 조회하도록 설정
- 수정, 삭제 URL은 조금더 고민해보기

* feat(reply) : 대댓글 작성 로직 및 API 개발

* fix(comment) : 댓글 조회 API 오류 해결
- 댓글 조회시, 같은 게시글에 달린 대댓글이 중복으로 조회되는 문제 해결
- 댓글 중 parent(부모댓글) 이 null 값인 것들만 조회하도록 수정

* chore : 사용하지 않는 병수 및 의존성 제거

* fix(post) : 게시글 조회 API 오류 해결
- 게시글도 댓글과 마찬가지로 조회시, 같은 게시글에 달린 대댓글이 중복으로 조회되는 문제 해결
- 댓글 중 parent(부모댓글) 이 null 값인 것들만 조회하는 메소드를 게시글 service에도 적용

* chore: 사용되지 않는 메소드 리턴 제거

* chore : validation 의존성 추가

* feat : Dto 에 validation 추가

* feat: 댓글 API,유효성 검증 실패시 예외처리 추가
- validation 실패시 발생하는 MethodArgumentNotValidException은 try-catch로는 잡히지 않아, 전역 핸들러 추가

* chore: 미사용 메소드 삭제

* chore: import 정리

* chore: 경고 제거

* feat(test) : post 단위, 통합 테스트 구현

---------

Co-authored-by: tomchccom <dreamkms2014@gmail.com>

---------

Co-authored-by: tomchccom <dreamkms2014@gmail.com>
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.

2 participants