From 75aa3f73ee7dd483d4abb4260aa550f4920fff5d Mon Sep 17 00:00:00 2001 From: kangnyy Date: Tue, 7 Apr 2026 22:10:02 +0900 Subject: [PATCH] =?UTF-8?q?[ADD]=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EC=A3=BC=EC=84=9D=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++ settings.gradle | 3 ++ .../likelion/session/SessionApplication.java | 2 +- .../session/controller/BoardController.java | 36 +++++++++---------- .../com/likelion/session/domain/Board.java | 36 ++++++++++--------- .../session/dto/BoardCreateRequest.java | 14 ++++---- .../likelion/session/dto/BoardResponse.java | 6 ++-- .../session/dto/BoardUpdateRequest.java | 13 ++++--- .../session/service/BoardService.java | 14 ++++---- 9 files changed, 67 insertions(+), 60 deletions(-) diff --git a/build.gradle b/build.gradle index deca6ed..c023a2e 100644 --- a/build.gradle +++ b/build.gradle @@ -26,6 +26,9 @@ 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/settings.gradle b/settings.gradle index ade3347..a3395b4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,4 @@ +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' +} rootProject.name = 'session' diff --git a/src/main/java/com/likelion/session/SessionApplication.java b/src/main/java/com/likelion/session/SessionApplication.java index 658e562..0359a9c 100644 --- a/src/main/java/com/likelion/session/SessionApplication.java +++ b/src/main/java/com/likelion/session/SessionApplication.java @@ -3,7 +3,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -@SpringBootApplication +@SpringBootApplication // 스프링부트 시작 클래스 (설정 + 컴포넌트 스캔 + 자동 설정 포함) 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..91cf4e1 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 컨트롤러 (JSON 형태로 응답 반환) +@RequestMapping("/boards") // 공통 URL 경로 설정 (/boards로 시작) +@RequiredArgsConstructor // final 필드에 대한 생성자 자동 생성 (의존성 주입용) public class BoardController { - private final ; + private final BoardService boardService; /* 게시글 생성 @@ -32,56 +32,56 @@ public class BoardController { -> 결과 반환 -> JSON 응답 */ - @Operation( + @Operation( // API 문서용 어노테이션 (Swagger/OpenAPI에서 설명 추가) summary = "게시글 생성", description = "새로운 게시글을 생성합니다." ) - @ - public ResponseEntity create(@RequestBody BoardCreateRequest request) { + @PostMapping // POST 요청 처리 (데이터 생성) + public ResponseEntity create(@RequestBody BoardCreateRequest request) { // 요청 본문(JSON)을 객체로 변환 BoardResponse response = boardService.create(request); return ResponseEntity.ok(response); } // 게시글 전체 조회 - @Operation( + @Operation( // API 문서용 어노테이션 (Swagger/OpenAPI에서 설명 추가) summary = "게시글 전체 조회", description = "등록된 모든 게시글을 조회합니다." ) - @ + @GetMapping // GET 요청 처리 (데이터 조회) public ResponseEntity> findAll() { List response = boardService.findAll(); return ResponseEntity.ok(response); } // 게시글 단건 조회 - @Operation( + @Operation( // API 문서용 어노테이션 (Swagger/OpenAPI에서 설명 추가) summary = "게시글 단건 조회", description = "id로 특정 게시글을 조회합니다." ) - @GetMapping("/{id}") - public ResponseEntity findById(@PathVariable Long id) { + @GetMapping("/{id}") // GET 요청 처리 (데이터 조회) + public ResponseEntity findById(@PathVariable Long id) { // URL 경로에 있는 값을 변수로 받음(/boards/{id}) BoardResponse response = boardService.findById(id); return ResponseEntity.ok(response); } // 게시글 수정 - @Operation( + @Operation( // API 문서용 어노테이션 (Swagger/OpenAPI에서 설명 추가) summary = "게시글 수정", description = "id로 특정 게시글의 제목과 내용을 수정합니다." ) - @("/{id}") - public ResponseEntity update(@PathVariable Long id, - @RequestBody BoardUpdateRequest request) { + @PutMapping("/{id}") // PUT 요청 처리 (데이터 수정) + public ResponseEntity update(@PathVariable Long id, //URL의 {id} 값을 추출하는 어노테이션 + @RequestBody BoardUpdateRequest request) { // JSON 본문을 Java 객체로 자동 변환해줌. BoardResponse response = boardService.update(id, request); return ResponseEntity.ok(response); } // 게시글 삭제 - @Operation( + @Operation( // API 문서용 어노테이션 (Swagger/OpenAPI에서 설명 추가) summary = "게시글 삭제", description = "id로 특정 게시글을 삭제합니다." ) - @("/{id}") + @DeleteMapping("/{id}") // 데이터 삭제 public ResponseEntity delete(@PathVariable Long id) { boardService.delete(id); return ResponseEntity.noContent().build(); diff --git a/src/main/java/com/likelion/session/domain/Board.java b/src/main/java/com/likelion/session/domain/Board.java index cb873de..85c11eb 100644 --- a/src/main/java/com/likelion/session/domain/Board.java +++ b/src/main/java/com/likelion/session/domain/Board.java @@ -10,34 +10,36 @@ @Getter // getter 메서드 자동 생성 @Entity // 해당 클래스 DB 테이블로 인식하고 관리 -@Table(name = "boards") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor +@Table(name = "boards") // 실제 DB에 생성될 테이블 이름 지정. 없으면 클래스 이름(Board)이 테이블 이름이 됨. +@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자 생성 (protected 접근 제한) +@AllArgsConstructor // 모든 필드를 포함한 생성자 생성 public class Board { - @Id + @Id // 이 필드가 테이블의 기본키(Primary Key)임을 나타냄. @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long ; + // id 값을 DB가 자동으로 1, 2, 3... 순서대로 증가(auto increment)시켜 직접 1, 2, 3, ..을 입력할 필요 없음 + private Long id; + // @Column() 해당컬럼의 옵션 설정 // 게시글 제목 - @Column(nullable = false, length = 100) - private String ; + @Column(nullable = false, length = 100) // null 불가 + 최대 길이 100 + private String title; // 게시글 내용 - @Column(nullable = false, columnDefinition = "TEXT") - private String ; + @Column(nullable = false, columnDefinition = "TEXT") // null 불가 + TEXT 타입으로 지정 + private String content; // 작성자 - @Column(nullable = false, length = 30) - private String ; + @Column(nullable = false, length = 30) // null 불가 + 최대 길이 30 + private String writer; // 생성 시간 - @Column(nullable = false) - private LocalDateTime ; + @Column(nullable = false) // null 불가 + private LocalDateTime createdAt; // 수정 시간 - @Column(nullable = false) - private LocalDateTime ; + @Column(nullable = false) // null 불가 + private LocalDateTime updatedAt; public Board(String title, String content, String writer) { @@ -46,13 +48,13 @@ public Board(String title, String content, String writer) { this.writer = writer; } - @PrePersist + @PrePersist // 엔티티 저장 전에 실행되는 메서드 public void prePersist() { this.createdAt = LocalDateTime.now(); this.updatedAt = LocalDateTime.now(); } - @PreUpdate + @PreUpdate // 엔티티 수정 직전에 실행되는 메서드 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..680830a 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 // 모든 필드의 getter 메서드 자동 생성 +@Setter // 모든 필드의 setter 메서드 자동 생성 +@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..c2ad6f8 100644 --- a/src/main/java/com/likelion/session/dto/BoardResponse.java +++ b/src/main/java/com/likelion/session/dto/BoardResponse.java @@ -6,9 +6,9 @@ import java.time.LocalDateTime; -@Getter -@AllArgsConstructor -@Builder +@Getter // 모든 필드의 getter 메서드 자동 생성 +@AllArgsConstructor // 모든 필드를 포함한 생성자 생성 +@Builder // 빌더 패턴 생성 (객체를 유연하게 생성 가능) 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..a17813a 100644 --- a/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java +++ b/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java @@ -7,15 +7,14 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; -@Getter -@Setter -@NoArgsConstructor +@Getter // 모든 필드의 getter 메서드 자동 생성 +@Setter // 모든 필드의 setter 메서드 자동 생성 +@NoArgsConstructor // 기본 생성자 생성 public class BoardUpdateRequest { - @NotBlank(message = "제목은 필수입니다.") - @Size(max = 100, message = "제목은 100자 이하로 입력해주세요.") + @NotBlank(message = "제목은 필수입니다.") // 공백/빈 문자열 금지 (유효성 검사) + @Size(max = 100, message = "제목은 100자 이하로 입력해주세요.") // 문자열 길이 제한 private String title; - @NotBlank(message = "내용은 필수입니다.") + @NotBlank(message = "내용은 필수입니다.") // 공백/빈 문자열 금지 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..af3e702 100644 --- a/src/main/java/com/likelion/session/service/BoardService.java +++ b/src/main/java/com/likelion/session/service/BoardService.java @@ -12,13 +12,13 @@ import java.util.List; -@Slf4j -@Service -@RequiredArgsConstructor -@Transactional +@Slf4j // log 객체 자동 생성 (로깅용) +@Service // 이 클래스가 비즈니스 로직 담당임을 Spring에 알려줌. +@RequiredArgsConstructor //final이 붙은 필드(boardRepository)를 생성자로 자동 주입해줌 +@Transactional //DB 작업 도중 에러가 나면 모든 작업을 이전으로 롤백함 public class BoardService { - private final ; + private final BoardRepository boardRepository; /* 게시글 생성 @@ -51,7 +51,7 @@ public BoardResponse create(BoardCreateRequest request) { - DB에 있는 모든 게시글을 가져옴 - Entity 리스트를 Response DTO 리스트로 변환 */ - @Transactional(readOnly = true) + @Transactional(readOnly = true) // 조회 전용 설정으로 성능 최적화에 씀 public List findAll() { return boardRepository.findAll() .stream() @@ -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));