From 098a8c29245e164e80d4e2bbc35b9695b09e2cb5 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Fri, 3 Oct 2025 17:17:56 +0900
Subject: [PATCH 01/17] Update README.md
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index 395edc5..82642b2 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
# backend-study-sns
+
+강준이
From 3d54a1fe17f3315982c7340a09fbd545c7913d97 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Sun, 5 Oct 2025 23:20:01 +0900
Subject: [PATCH 02/17] chore: add JPA and Lombok dependencies
---
build.gradle | 8 +++++++
.../com/example/devSns/controller/explanation | 1 +
.../java/com/example/devSns/dto/explanation | 8 +++++++
.../com/example/devSns/entity/PostEntity.java | 0
.../com/example/devSns/entity/explanation | 22 +++++++++++++++++++
.../com/example/devSns/repository/explanation | 1 +
.../com/example/devSns/service/explanation | 1 +
7 files changed, 41 insertions(+)
create mode 100644 src/main/java/com/example/devSns/controller/explanation
create mode 100644 src/main/java/com/example/devSns/dto/explanation
create mode 100644 src/main/java/com/example/devSns/entity/PostEntity.java
create mode 100644 src/main/java/com/example/devSns/entity/explanation
create mode 100644 src/main/java/com/example/devSns/repository/explanation
create mode 100644 src/main/java/com/example/devSns/service/explanation
diff --git a/build.gradle b/build.gradle
index 610d6a6..c78d56d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -19,8 +19,16 @@ repositories {
}
dependencies {
+ // Lombok
+ compileOnly 'org.projectlombok:lombok'
+ annotationProcessor 'org.projectlombok:lombok'
+
implementation 'org.springframework.boot:spring-boot-starter-web'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+ implementation 'org.springframework.boot:spring-boot-starter-jdbc'
+ implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ runtimeOnly 'com.h2database:h2' // 임시 메모리 DB
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
diff --git a/src/main/java/com/example/devSns/controller/explanation b/src/main/java/com/example/devSns/controller/explanation
new file mode 100644
index 0000000..3191f3e
--- /dev/null
+++ b/src/main/java/com/example/devSns/controller/explanation
@@ -0,0 +1 @@
+요청을 받는 곳
\ No newline at end of file
diff --git a/src/main/java/com/example/devSns/dto/explanation b/src/main/java/com/example/devSns/dto/explanation
new file mode 100644
index 0000000..095c837
--- /dev/null
+++ b/src/main/java/com/example/devSns/dto/explanation
@@ -0,0 +1,8 @@
+계층간 데이터 교환에 사용
+- Entity 클래스를 보호
+- 필요한 데이터만 선택적으로 담을 수 있음
+
+분리해서 사용하는 이유
+- Entity 객체의 변경을 피하기 위함
+- 클라이언트와 통신하는 ResponseDTO나 RequestDTO는 요구사항에 따라 자주 변경
+- 어떤 요청에서는 특정 값이 추가되거나 없을 수 있어서 분리해서 관리
\ No newline at end of file
diff --git a/src/main/java/com/example/devSns/entity/PostEntity.java b/src/main/java/com/example/devSns/entity/PostEntity.java
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/java/com/example/devSns/entity/explanation b/src/main/java/com/example/devSns/entity/explanation
new file mode 100644
index 0000000..402a31e
--- /dev/null
+++ b/src/main/java/com/example/devSns/entity/explanation
@@ -0,0 +1,22 @@
+데이터베이스와 직접적으로 맞닿는 핵심적인 클래스
+- entity를 기준으로 테이블 생성
+- Builder 패턴을 사용해서 필요한 값만 넣음
+
+PostEntity 객체가 곧 DB의 한 행(row)
+-> 기본 키는 id이고, 나머지는 속성임을 명시하는 클래스
+
+@Entity
+데이터베이스 테이블과 매핑
+- JPA가 이 클래스를 테이블로 인식
+- 데이터베이스 테이블로 매핑할 수 있게 함
+
+@Id
+해당 필드가 기본 키임을 나타냄
+- JPA에서 이 필드는 각 행을 고유하게 식별하는 기준
+
+@GeneratedValue
+기본 키의 값을 자동 생성할 때 어떤 전략을 쓸지 지정
+GenerationType.IDENTITY는 자동 증가
+
+@Getter, @Setter (Lombok)
+보일러플레이트 제거
\ No newline at end of file
diff --git a/src/main/java/com/example/devSns/repository/explanation b/src/main/java/com/example/devSns/repository/explanation
new file mode 100644
index 0000000..97a040b
--- /dev/null
+++ b/src/main/java/com/example/devSns/repository/explanation
@@ -0,0 +1 @@
+데이터베이스 접근 (JPA 인터페이스)
\ No newline at end of file
diff --git a/src/main/java/com/example/devSns/service/explanation b/src/main/java/com/example/devSns/service/explanation
new file mode 100644
index 0000000..7417adb
--- /dev/null
+++ b/src/main/java/com/example/devSns/service/explanation
@@ -0,0 +1 @@
+비지니스 로직 담당
\ No newline at end of file
From 2ded9e9a476a70f082d8378cd63dc9ba70ba46ce Mon Sep 17 00:00:00 2001
From: junyi04
Date: Sun, 5 Oct 2025 23:25:04 +0900
Subject: [PATCH 03/17] feat(docs): add PostEntity and explanation
---
.../com/example/devSns/entity/PostEntity.java | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/main/java/com/example/devSns/entity/PostEntity.java b/src/main/java/com/example/devSns/entity/PostEntity.java
index e69de29..058a89a 100644
--- a/src/main/java/com/example/devSns/entity/PostEntity.java
+++ b/src/main/java/com/example/devSns/entity/PostEntity.java
@@ -0,0 +1,22 @@
+package com.example.devSns.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import lombok.Getter;
+import lombok.Setter;
+
+@Entity
+@Getter
+@Setter
+public class PostEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String title;
+ private String content;
+ private String author;
+}
\ No newline at end of file
From 259201710a9469596ddb17f88c199ac178d0bdee Mon Sep 17 00:00:00 2001
From: junyi04
Date: Sun, 5 Oct 2025 23:28:38 +0900
Subject: [PATCH 04/17] feat(docs): add PostRepository and explanation
---
.../java/com/example/devSns/repository/PostRepository.java | 7 +++++++
src/main/java/com/example/devSns/repository/explanation | 6 +++++-
2 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/example/devSns/repository/PostRepository.java
diff --git a/src/main/java/com/example/devSns/repository/PostRepository.java b/src/main/java/com/example/devSns/repository/PostRepository.java
new file mode 100644
index 0000000..d6e24c5
--- /dev/null
+++ b/src/main/java/com/example/devSns/repository/PostRepository.java
@@ -0,0 +1,7 @@
+package com.example.devSns.repository;
+
+import com.example.devSns.entity.PostEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PostRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/example/devSns/repository/explanation b/src/main/java/com/example/devSns/repository/explanation
index 97a040b..235ff10 100644
--- a/src/main/java/com/example/devSns/repository/explanation
+++ b/src/main/java/com/example/devSns/repository/explanation
@@ -1 +1,5 @@
-데이터베이스 접근 (JPA 인터페이스)
\ No newline at end of file
+데이터베이스 접근 (JPA 인터페이스)
+
+PostRepository
+상속만 하면 기본 CRUD가 다 생김
+- save, findAll, findById, deleteById
From a8694623d8149b1c8a16be2e99a09e3b715de7c4 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Sun, 5 Oct 2025 23:45:04 +0900
Subject: [PATCH 05/17] feat(docs): add PostService and explanation
---
.../example/devSns/service/PostService.java | 46 +++++++++++++++++++
.../com/example/devSns/service/explanation | 34 +++++++++++++-
2 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/example/devSns/service/PostService.java
diff --git a/src/main/java/com/example/devSns/service/PostService.java b/src/main/java/com/example/devSns/service/PostService.java
new file mode 100644
index 0000000..c9630f9
--- /dev/null
+++ b/src/main/java/com/example/devSns/service/PostService.java
@@ -0,0 +1,46 @@
+package com.example.devSns.service;
+
+import com.example.devSns.entity.PostEntity;
+import com.example.devSns.repository.PostRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional(readOnly = true)
+public class PostService {
+ private final PostRepository postRepository;
+
+ // 생성자
+ public PostService(PostRepository postRepository) {
+ this.postRepository = postRepository;
+ }
+
+ public List getAllPosts() {
+ return postRepository.findAll();
+ }
+
+ public PostEntity getPost(Long id) {
+ return postRepository.findById(id).orElseThrow();
+ }
+
+ @Transactional
+ public PostEntity createPost(PostEntity postEntity) {
+ return postRepository.save(postEntity);
+ }
+
+ @Transactional
+ public PostEntity updatePost(Long id, PostEntity updated) {
+ PostEntity postEntity = postRepository.findById(id).orElseThrow();
+ postEntity.setTitle(updated.getTitle());
+ postEntity.setContent(updated.getContent());
+ return postRepository.save(postEntity);
+ }
+
+ @Transactional
+ public void deletePost(Long id) {
+ postRepository.deleteById(id);
+ }
+
+}
diff --git a/src/main/java/com/example/devSns/service/explanation b/src/main/java/com/example/devSns/service/explanation
index 7417adb..09b39f6 100644
--- a/src/main/java/com/example/devSns/service/explanation
+++ b/src/main/java/com/example/devSns/service/explanation
@@ -1 +1,33 @@
-비지니스 로직 담당
\ No newline at end of file
+비지니스 로직 담당
+
+PostService
+
+@Service
+비지니스 로직이 모이는 곳
+- 트랜잭션을 붙여야 할 때도 주로 서비스에서
+- 의존성 주입 (생성자 주입)
+
+@Transactional(readOnly = true)
+읽기 성능 최적화
+- 원자성 보장
+- 안전빵
+
+private final PostRepository postRepository;
+- 의존성으로 받는 레포지토리
+- 생성자 주입
+- JpaRepository 상속
+
+findAll()
+- 모든 게시글 조회
+
+findById()
+- getPost 함수에서 PK(id)로 단건 조회
+- updatePost 함수에서 수정 대상 로드, 필드 갱신, 저장
+
+save
+- 새 엔터티 저장
+- id가 없으면 persist, 있으면 merge
+
+deleteById
+- PK(id)로 삭제
+
From 9346fa92ae83ccd151afc02a412334540f5f73c2 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Mon, 6 Oct 2025 00:02:45 +0900
Subject: [PATCH 06/17] feat(docs): add PostController and explanation
---
.../devSns/controller/PostController.java | 54 +++++++++++++++++++
.../com/example/devSns/controller/explanation | 25 ++++++++-
2 files changed, 78 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/com/example/devSns/controller/PostController.java
diff --git a/src/main/java/com/example/devSns/controller/PostController.java b/src/main/java/com/example/devSns/controller/PostController.java
new file mode 100644
index 0000000..99dc55a
--- /dev/null
+++ b/src/main/java/com/example/devSns/controller/PostController.java
@@ -0,0 +1,54 @@
+package com.example.devSns.controller;
+
+import com.example.devSns.entity.PostEntity;
+import com.example.devSns.service.PostService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+@Controller
+@RequestMapping("/posts")
+public class PostController {
+
+ private final PostService postService;
+
+ // 생성자
+ public PostController(PostService postService) {
+ this.postService = postService;
+ }
+
+ // HTTP GET /posts
+ @GetMapping
+ public String list(Model model) {
+ model.addAttribute("posts", postService.getAllPosts());
+ return "list";
+ }
+
+ // HTTP GET /posts/new
+ @GetMapping("/new")
+ public String form(Model model) {
+ model.addAttribute("post", new PostEntity());
+ return "form";
+ }
+
+ // HTTP POST /posts
+ @PostMapping
+ public String create(@ModelAttribute PostEntity postEntity) {
+ postService.createPost(postEntity);
+ return "redirect:/posts";
+ }
+
+ // HTTP GET /posts/{id}
+ @GetMapping("/{id}")
+ public String detail(@PathVariable Long id, Model model) {
+ model.addAttribute("post", postService.getPost(id));
+ return "detail";
+ }
+
+ // HTTP POST /posts/{id}/delete
+ @PostMapping("/{id}/delete")
+ public String delete(@PathVariable Long id) {
+ postService.deletePost(id);
+ return "redirect:/posts";
+ }
+}
diff --git a/src/main/java/com/example/devSns/controller/explanation b/src/main/java/com/example/devSns/controller/explanation
index 3191f3e..d86130e 100644
--- a/src/main/java/com/example/devSns/controller/explanation
+++ b/src/main/java/com/example/devSns/controller/explanation
@@ -1 +1,24 @@
-요청을 받는 곳
\ No newline at end of file
+요청을 받는 곳
+
+PostController
+Spring MVC 패턴에서 Controller 계층 역할
+- 사용자의 요청을 받고 Service 계층을 호출해서 처리한 후, 결과를 View에 전달
+
+@Controller
+이 클래스는 웹 요청을 처리하는 컨트롤러임을 알려줌
+- Model에 데이터를 담아 템플릿에 전달 (templates/list.html)
+
+@RequestMapping
+클래스 전체의 기본 URL 경로를 지정
+- 이 컨트롤러 안의 모든 요청은 /posts로 시작
+- /posts (게시글 목록), /posts/new (새 글 작성 폼)
+
+@GetMapping, @PostMapping
+HTTP 메서드 별 라우팅
+
+@PathVariable, @ModelAttribute
+URL 경로 변수 바인딩 / 폼 데이터를 객체에 바인딩
+
+@RestController
+문자열 반환이 뷰 이름이 아닌 JSON
+- REST API 만들 때 사용
\ No newline at end of file
From e22712679ec7e479cba646ca81dd9e1d8540705c Mon Sep 17 00:00:00 2001
From: junyi04
Date: Mon, 6 Oct 2025 00:10:07 +0900
Subject: [PATCH 07/17] feat: create templates/list.html (/posts/new)
---
src/main/resources/templates/list.html | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 src/main/resources/templates/list.html
diff --git a/src/main/resources/templates/list.html b/src/main/resources/templates/list.html
new file mode 100644
index 0000000..712cbd7
--- /dev/null
+++ b/src/main/resources/templates/list.html
@@ -0,0 +1,12 @@
+
+
+
+ 게시판
+ 새 글 쓰기
+
+
+
\ No newline at end of file
From 96b956f37e5a15f397b812cb1ee9bbd5e5089ac7 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Mon, 6 Oct 2025 00:14:23 +0900
Subject: [PATCH 08/17] feat: create templates/form.html (/posts)
---
src/main/resources/templates/form.html | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 src/main/resources/templates/form.html
diff --git a/src/main/resources/templates/form.html b/src/main/resources/templates/form.html
new file mode 100644
index 0000000..52849d8
--- /dev/null
+++ b/src/main/resources/templates/form.html
@@ -0,0 +1,12 @@
+
+
+
+ 새 글 작성
+
+
+
\ No newline at end of file
From 845bb2d8175c93927a949ad46053d2ed2e4227d2 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Mon, 6 Oct 2025 00:18:19 +0900
Subject: [PATCH 09/17] feat: create templates/detail.html (/posts/{id}/delete)
---
src/main/resources/templates/detail.html | 15 +++++++++++++++
1 file changed, 15 insertions(+)
create mode 100644 src/main/resources/templates/detail.html
diff --git a/src/main/resources/templates/detail.html b/src/main/resources/templates/detail.html
new file mode 100644
index 0000000..c585343
--- /dev/null
+++ b/src/main/resources/templates/detail.html
@@ -0,0 +1,15 @@
+
+
+
+ 제목
+ 내용
+
+ 작성자:
+
+
+
+
+
+
\ No newline at end of file
From eb68811505190ff85662afb6d25ad349f4803f97 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Mon, 6 Oct 2025 00:33:59 +0900
Subject: [PATCH 10/17] chore: update H2 database and JPA configuration
---
src/main/resources/application.properties | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index f3f10af..8bef822 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,23 @@
spring.application.name=devSns
+
+# ?? ??
+server.port=8080
+
+# H2 ???? DB
+spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DATABASE_TO_UPPER=false
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=
+
+# JPA
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.format_sql=true
+
+# H2 ??
+spring.h2.console.enabled=true
+spring.h2.console.path=/h2-console
+
+# Thymeleaf(??? ??? ?? ?)
+spring.thymeleaf.cache=false
+
From 8000aaf512e2de6767950b7867370aebf04fbc31 Mon Sep 17 00:00:00 2001
From: junyi04
Date: Mon, 6 Oct 2025 00:40:39 +0900
Subject: [PATCH 11/17] fix: correct typo in list.html&detail.html th name
---
src/main/resources/templates/detail.html | 2 +-
src/main/resources/templates/list.html | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/resources/templates/detail.html b/src/main/resources/templates/detail.html
index c585343..016c58c 100644
--- a/src/main/resources/templates/detail.html
+++ b/src/main/resources/templates/detail.html
@@ -8,7 +8,7 @@ 내용
-