From 72120873dd451c3fe670abc21834fbdaa172e4d0 Mon Sep 17 00:00:00 2001
From: hcfinai <202500804@hufs.ac.kr>
Date: Sun, 12 Apr 2026 13:45:46 +0900
Subject: [PATCH] =?UTF-8?q?=EC=84=B8=EC=85=98=20=EA=B3=BC=EC=A0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
SpringCRUDSession | 1 +
board/.gitignore | 15 +-------
board/src/Main.java | 15 ++++++++
board/src/main/resources/application.yml | 4 +--
build.gradle | 4 ++-
.../likelion/session/SessionApplication.java | 6 +++-
.../session/controller/BoardController.java | 32 ++++++++---------
.../com/likelion/session/domain/Board.java | 36 +++++++++----------
.../session/dto/BoardCreateRequest.java | 14 ++++----
.../likelion/session/dto/BoardResponse.java | 12 +++----
.../session/dto/BoardUpdateRequest.java | 22 ++++++------
.../session/service/BoardService.java | 20 +++++------
src/main/resources/application.yml | 28 +++++++++++++++
.../session/SessionApplicationTests.java | 4 +--
14 files changed, 125 insertions(+), 88 deletions(-)
create mode 160000 SpringCRUDSession
create mode 100644 board/src/Main.java
create mode 100644 src/main/resources/application.yml
diff --git a/SpringCRUDSession b/SpringCRUDSession
new file mode 160000
index 0000000..a60be9f
--- /dev/null
+++ b/SpringCRUDSession
@@ -0,0 +1 @@
+Subproject commit a60be9f25e5bbc4aed7efc88d5bfbd969cc57492
diff --git a/board/.gitignore b/board/.gitignore
index 1fac4d5..13275f1 100644
--- a/board/.gitignore
+++ b/board/.gitignore
@@ -1,21 +1,8 @@
-.gradle
-build/
-!gradle/wrapper/gradle-wrapper.jar
-!**/src/main/**/build/
-!**/src/test/**/build/
-.kotlin
-
### IntelliJ IDEA ###
-.idea/modules.xml
-.idea/jarRepositories.xml
-.idea/compiler.xml
-.idea/libraries/
-*.iws
-*.iml
-*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
+.kotlin
### Eclipse ###
.apt_generated
diff --git a/board/src/Main.java b/board/src/Main.java
new file mode 100644
index 0000000..24f7aa3
--- /dev/null
+++ b/board/src/Main.java
@@ -0,0 +1,15 @@
+//TIP 코드를 실행하려면 을(를) 누르거나
+// 에디터 여백에 있는 아이콘을 클릭하세요.
+public class Main {
+ public static void main(String[] args) {
+ //TIP 캐럿을 강조 표시된 텍스트에 놓고 을(를) 누르면
+ // IntelliJ IDEA이(가) 수정을 제안하는 것을 확인할 수 있습니다.
+ System.out.printf("Hello and welcome!");
+
+ for (int i = 1; i <= 5; i++) {
+ //TIP 을(를) 눌러 코드 디버그를 시작하세요. 1개의 중단점을 설정해 드렸습니다
+ // 언제든 을(를) 눌러 중단점을 더 추가할 수 있습니다.
+ System.out.println("i = " + i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/board/src/main/resources/application.yml b/board/src/main/resources/application.yml
index 4733b81..1ac5cf3 100644
--- a/board/src/main/resources/application.yml
+++ b/board/src/main/resources/application.yml
@@ -1,5 +1,5 @@
server:
- port: 8080
+ port: 8082
spring:
application:
@@ -9,7 +9,7 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/session?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: root
- password: yebin1448!
+ password: Guscjf#@4944
jpa:
hibernate:
diff --git a/build.gradle b/build.gradle
index deca6ed..9a7e708 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ version = '0.0.1-SNAPSHOT'
java {
toolchain {
- languageVersion = JavaLanguageVersion.of(21)
+ languageVersion = JavaLanguageVersion.of(26)
}
}
@@ -26,6 +26,8 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
+ implementation 'org.springframework.boot:spring-boot-starter-validation'
+ implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
diff --git a/src/main/java/com/likelion/session/SessionApplication.java b/src/main/java/com/likelion/session/SessionApplication.java
index 658e562..8a26f84 100644
--- a/src/main/java/com/likelion/session/SessionApplication.java
+++ b/src/main/java/com/likelion/session/SessionApplication.java
@@ -1,9 +1,13 @@
package com.likelion.session;
import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;//스프링 부트 애플리케이션의 시작점(진입점) 을 나타내는 어노테이션
@SpringBootApplication
+//스프링 부트 애플리케이션의 시작점(진입점) 을 나타내는 어노테이션(3개가 합쳐진 것)
+//@SpringBootConfiguration 설정 클래스로 등록 (@Configuration과 동일)
+//+ @EnableAutoConfiguration 스프링 부트 자동 설정 활성화
+//+ @ComponentScan 현재 패키지 하위의 빈 자동 스캔
public class SessionApplication {
public static void main(String[] args) {
diff --git a/src/main/java/com/likelion/session/controller/BoardController.java b/src/main/java/com/likelion/session/controller/BoardController.java
index 2af74e7..415c919 100644
--- a/src/main/java/com/likelion/session/controller/BoardController.java
+++ b/src/main/java/com/likelion/session/controller/BoardController.java
@@ -11,12 +11,12 @@
import java.util.List;
-@RestController
-@RequestMapping("/boards")
-@RequiredArgsConstructor
+@RestController//REST API 컨트롤러
+@RequestMapping("/boards")//Spring MVC에서 HTTP 요청을 특정 메서드나 클래스에 매핑
+@RequiredArgsConstructor//final 또는 @NonNull 필드를 매개변수로 받는 생성자를 자동으로 생성
public class BoardController {
- private final ;
+ private final BoardService boardService;
/*
게시글 생성
@@ -32,44 +32,44 @@ public class BoardController {
-> 결과 반환
-> JSON 응답
*/
- @Operation(
+ @Operation(//API 문서에서 엔드포인트에 대한 설명을 작성할 때 사용
summary = "게시글 생성",
description = "새로운 게시글을 생성합니다."
)
- @
+ @PostMapping//Spring MVC에서 HTTP POST 요청을 특정 메서드에 매핑 @RequestMapping의 축약형
public ResponseEntity create(@RequestBody BoardCreateRequest request) {
BoardResponse response = boardService.create(request);
return ResponseEntity.ok(response);
}
// 게시글 전체 조회
- @Operation(
+ @Operation(//API 문서에서 엔드포인트에 대한 설명을 작성할 때 사용
summary = "게시글 전체 조회",
description = "등록된 모든 게시글을 조회합니다."
)
- @
+ @GetMapping//GET 요청 매핑
public ResponseEntity> findAll() {
List response = boardService.findAll();
return ResponseEntity.ok(response);
}
// 게시글 단건 조회
- @Operation(
+ @Operation(//API 문서에서 엔드포인트에 대한 설명을 작성할 때 사용
summary = "게시글 단건 조회",
description = "id로 특정 게시글을 조회합니다."
)
- @GetMapping("/{id}")
- public ResponseEntity findById(@PathVariable Long id) {
+ @GetMapping("/{id}")//GET 요청 매핑
+ public ResponseEntity findById(@PathVariable Long id) {//URL 경로의 변수 값을 메서드 파라미터로 추출
BoardResponse response = boardService.findById(id);
return ResponseEntity.ok(response);
}
// 게시글 수정
- @Operation(
+ @Operation(//API 문서에서 엔드포인트에 대한 설명을 작성할 때 사용
summary = "게시글 수정",
description = "id로 특정 게시글의 제목과 내용을 수정합니다."
)
- @("/{id}")
+ @PutMapping("/{id}")//HTTP PUT 요청을 매핑하며, 리소스를 전체 교체할 때 사용
public ResponseEntity update(@PathVariable Long id,
@RequestBody BoardUpdateRequest request) {
BoardResponse response = boardService.update(id, request);
@@ -77,13 +77,13 @@ public ResponseEntity update(@PathVariable Long id,
}
// 게시글 삭제
- @Operation(
+ @Operation(//API 문서에서 엔드포인트에 대한 설명을 작성할 때 사용
summary = "게시글 삭제",
description = "id로 특정 게시글을 삭제합니다."
)
- @("/{id}")
+ @DeleteMapping("/{id}")//HTTP DELETE 요청을 매핑하며, 리소스를 삭제할 때 사용
public ResponseEntity delete(@PathVariable Long id) {
boardService.delete(id);
return ResponseEntity.noContent().build();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/likelion/session/domain/Board.java b/src/main/java/com/likelion/session/domain/Board.java
index cb873de..924b0be 100644
--- a/src/main/java/com/likelion/session/domain/Board.java
+++ b/src/main/java/com/likelion/session/domain/Board.java
@@ -10,34 +10,34 @@
@Getter // getter 메서드 자동 생성
@Entity // 해당 클래스 DB 테이블로 인식하고 관리
-@Table(name = "boards")
-@NoArgsConstructor(access = AccessLevel.PROTECTED)
-@AllArgsConstructor
+@Table(name = "boards")//JPA(Java Persistence API) 에서 엔티티 클래스와 데이터베이스 테이블을 매핑할 때 사용
+@NoArgsConstructor(access = AccessLevel.PROTECTED)//기본 생성자(파라미터 없는 생성자)를 자동 생성
+@AllArgsConstructor//모든 필드를 매개변수로 받는 생성자를 자동 생성
public class Board {
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- private Long ;
+ @Id//JPA에서 엔티티의 기본 키(Primary Key) 를 지정하는 어노테이션
+ @GeneratedValue(strategy = GenerationType.IDENTITY)//JPA에서 기본 키(PK) 값을 자동으로 생성하는 전략을 지정
+ private Long id;
// 게시글 제목
- @Column(nullable = false, length = 100)
- private String ;
+ @Column(nullable = false, length = 100)//JPA에서 엔티티 필드와 DB 컬럼을 매핑하고 세부 속성을 설정
+ private String title;
// 게시글 내용
- @Column(nullable = false, columnDefinition = "TEXT")
- private String ;
+ @Column(nullable = false, columnDefinition = "TEXT")//JPA에서 엔티티 필드와 DB 컬럼을 매핑하고 세부 속성을 설정
+ private String content;
// 작성자
- @Column(nullable = false, length = 30)
- private String ;
+ @Column(nullable = false, length = 30)//JPA에서 엔티티 필드와 DB 컬럼을 매핑하고 세부 속성을 설정
+ private String writer;
// 생성 시간
- @Column(nullable = false)
- private LocalDateTime ;
+ @Column(nullable = false)//JPA에서 엔티티 필드와 DB 컬럼을 매핑하고 세부 속성을 설정
+ private LocalDateTime createdAt;
// 수정 시간
- @Column(nullable = false)
- private LocalDateTime ;
+ @Column(nullable = false)//JPA에서 엔티티 필드와 DB 컬럼을 매핑하고 세부 속성을 설정
+ private LocalDateTime updatedAt;
public Board(String title, String content, String writer) {
@@ -46,13 +46,13 @@ public Board(String title, String content, String writer) {
this.writer = writer;
}
- @PrePersist
+ @PrePersist //JPA에서 엔티티가 최초로 저장(INSERT)되기 직전에 자동으로 실행되는 메서드를 지정
public void prePersist() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
- @PreUpdate
+ @PreUpdate //엔티티가 수정(UPDATE)되기 직전에 자동으로 실행되는 메서드를 지정
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
diff --git a/src/main/java/com/likelion/session/dto/BoardCreateRequest.java b/src/main/java/com/likelion/session/dto/BoardCreateRequest.java
index 62b1821..7792401 100644
--- a/src/main/java/com/likelion/session/dto/BoardCreateRequest.java
+++ b/src/main/java/com/likelion/session/dto/BoardCreateRequest.java
@@ -5,13 +5,13 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
-@Getter
-@Setter
-@NoArgsConstructor
-@AllArgsConstructor
+@Getter //모든 필드의 get 메서드 자동 생성
+@Setter //모든 필드의 set 메서드 자동 생성
+@NoArgsConstructor //기본 생성자 자동 생성
+@AllArgsConstructor //모든 필드를 매개변수로 받는 생성자 자동 생성
public class BoardCreateRequest {
// 넘겨주고 싶은 정보: 제목(title), 내용(content), 작성자(writer)
- private String ;
- private String ;
- private String ;
+ private String title;
+ private String content;
+ private String writer;
}
\ No newline at end of file
diff --git a/src/main/java/com/likelion/session/dto/BoardResponse.java b/src/main/java/com/likelion/session/dto/BoardResponse.java
index dc6e74f..b0266a9 100644
--- a/src/main/java/com/likelion/session/dto/BoardResponse.java
+++ b/src/main/java/com/likelion/session/dto/BoardResponse.java
@@ -1,14 +1,14 @@
package com.likelion.session.dto;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
+import lombok.AllArgsConstructor;//모든 필드를 매개변수로 받는 생성자 자동 생성
+import lombok.Builder;//빌더 패턴으로 객체 생성 가능하게 해주는 Lombok 어노테이션
+import lombok.Getter;//모든 필드의 get 메서드 자동 생성
import java.time.LocalDateTime;
-@Getter
-@AllArgsConstructor
-@Builder
+@Getter//모든 필드의 get 메서드 자동 생성
+@AllArgsConstructor//모든 필드를 매개변수로 받는 생성자 자동 생성
+@Builder//빌더 패턴으로 객체 생성 가능하게 해주는 Lombok 어노테이션
public class BoardResponse {
// 돌려주고 싶은 응답: id, title, content, writer, createdAt, updatedAt
diff --git a/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java b/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java
index d1e98e4..122df35 100644
--- a/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java
+++ b/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java
@@ -1,21 +1,21 @@
package com.likelion.session.dto;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
+import lombok.Getter;//모든 필드의 get 메서드 자동 생성
+import lombok.NoArgsConstructor;//기본 생성자 자동 생성
+import lombok.Setter;//모든 필드의 set 메서드 자동 생성
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.Size;
+import jakarta.validation.constraints.NotBlank;//null, 빈 문자열, 공백 문자열 모두 허용하지 않는 유효성 검사 어노테이션
+import jakarta.validation.constraints.Size;//문자열 길이 또는 컬렉션 크기의 범위를 제한
-@Getter
-@Setter
-@NoArgsConstructor
+@Getter//모든 필드의 get 메서드 자동 생성
+@Setter//모든 필드의 set 메서드 자동 생성
+@NoArgsConstructor//기본 생성자 자동 생성
public class BoardUpdateRequest {
- @NotBlank(message = "제목은 필수입니다.")
- @Size(max = 100, message = "제목은 100자 이하로 입력해주세요.")
+ @NotBlank(message = "제목은 필수입니다.")//null, 빈 문자열, 공백 문자열 모두 허용하지 않는 유효성 검사 어노테이션
+ @Size(max = 100, message = "제목은 100자 이하로 입력해주세요.")//문자열 길이 또는 컬렉션 크기의 범위를 제한
private String title;
- @NotBlank(message = "내용은 필수입니다.")
+ @NotBlank(message = "내용은 필수입니다.")//null, 빈 문자열, 공백 문자열 모두 허용하지 않는 유효성 검사 어노테이션
private String content;
}
diff --git a/src/main/java/com/likelion/session/service/BoardService.java b/src/main/java/com/likelion/session/service/BoardService.java
index 1bc58af..01ecf86 100644
--- a/src/main/java/com/likelion/session/service/BoardService.java
+++ b/src/main/java/com/likelion/session/service/BoardService.java
@@ -5,20 +5,20 @@
import com.likelion.session.dto.BoardResponse;
import com.likelion.session.dto.BoardUpdateRequest;
import com.likelion.session.repository.BoardRepository;
-import org.springframework.transaction.annotation.Transactional;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;//메서드 또는 클래스에 트랜잭션을 적용하는 어노테이션
+import lombok.RequiredArgsConstructor;//final 필드만 매개변수로 받는 생성자를 자동 생성하는 Lombok 어노테이션
+import lombok.extern.slf4j.Slf4j;//로그를 출력하기 위한 Lombok 어노테이션
+import org.springframework.stereotype.Service;//해당 클래스가 비즈니스 로직을 처리하는 서비스 계층임을 선언하는 어노테이션
import java.util.List;
-@Slf4j
-@Service
-@RequiredArgsConstructor
-@Transactional
+@Slf4j//로그를 출력하기 위한 Lombok 어노테이션
+@Service//해당 클래스가 비즈니스 로직을 처리하는 서비스 계층임을 선언하는 어노테이션
+@RequiredArgsConstructor//final 필드만 매개변수로 받는 생성자를 자동 생성하는 Lombok 어노테이션
+@Transactional//메서드 또는 클래스에 트랜잭션을 적용하는 어노테이션
public class BoardService {
- private final ;
+ private final BoardRepository boardRepository;
/*
게시글 생성
@@ -71,7 +71,7 @@ public List findAll() {
- id로 게시글 조회
- 없으면 예외 발생
*/
- @Transactional(readOnly = true)
+ @Transactional(readOnly = true)//메서드 또는 클래스에 트랜잭션을 적용하는 어노테이션
public BoardResponse findById(Long id) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..1ac5cf3
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,28 @@
+server:
+ port: 8082
+
+spring:
+ application:
+ name: session
+
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://localhost:3306/session?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
+ username: root
+ password: Guscjf#@4944
+
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ properties:
+ hibernate:
+ format_sql: true
+
+ jackson:
+ serialization:
+ fail-on-empty-beans: false
+
+logging:
+ level:
+ org.hibernate.SQL: debug
\ No newline at end of file
diff --git a/src/test/java/com/likelion/session/SessionApplicationTests.java b/src/test/java/com/likelion/session/SessionApplicationTests.java
index b65f4a0..7416b06 100644
--- a/src/test/java/com/likelion/session/SessionApplicationTests.java
+++ b/src/test/java/com/likelion/session/SessionApplicationTests.java
@@ -3,10 +3,10 @@
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
-@SpringBootTest
+@SpringBootTest//스프링 부트 애플리케이션의 시작점(진입점) 을 나타내는 어노테이션
class SessionApplicationTests {
- @Test
+ @Test//JUnit에서 테스트 메서드임을 선언하는 어노테이션
void contextLoads() {
}