diff --git a/build.gradle b/build.gradle index deca6ed..915fb01 100644 --- a/build.gradle +++ b/build.gradle @@ -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..fdd97cc 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//Spring Boot의 핵심 설정 어노테이션 (안에 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..0cbb019 100644 --- a/src/main/java/com/likelion/session/controller/BoardController.java +++ b/src/main/java/com/likelion/session/controller/BoardController.java @@ -11,79 +11,73 @@ import java.util.List; -@RestController -@RequestMapping("/boards") -@RequiredArgsConstructor +/** + * BoardController + * 게시글 관련 요청을 처리하는 컨트롤러 + */ +@RestController // REST API 요청을 처리하는 컨트롤러로 선언 +@RequestMapping("/boards") // 공통 URL 경로 설정 +@RequiredArgsConstructor // final 필드를 자동으로 생성자 주입 public class BoardController { - private final ; + private final BoardService boardService; // 게시글 비즈니스 로직 처리 서비스 - /* - 게시글 생성 - - [요청 흐름] - Client - -> DispatcherServlet - -> HandlerMapping - -> BoardController의 create() 메서드 선택 - -> Service 호출 - -> Repository 호출 - -> DB 저장 - -> 결과 반환 - -> JSON 응답 - */ - @Operation( - summary = "게시글 생성", - description = "새로운 게시글을 생성합니다." + @Operation( // Swagger에서 API 문서 설명을 위한 어노테이션 + summary = "게시글 생성", // API 한 줄 요약 설명 + description = "새로운 게시글을 생성합니다." // API 상세 설명 ) - @ - public ResponseEntity create(@RequestBody BoardCreateRequest request) { + @PostMapping // HTTP POST 요청을 처리하는 매핑 + public ResponseEntity create( + @RequestBody BoardCreateRequest request // 요청 JSON 데이터를 객체로 변환 + ) { BoardResponse response = boardService.create(request); return ResponseEntity.ok(response); } - // 게시글 전체 조회 - @Operation( + @Operation( // Swagger 문서용 설명 summary = "게시글 전체 조회", description = "등록된 모든 게시글을 조회합니다." ) - @ + @GetMapping // HTTP GET 요청 처리 public ResponseEntity> findAll() { List response = boardService.findAll(); return ResponseEntity.ok(response); } - // 게시글 단건 조회 - @Operation( + @Operation( // Swagger 문서용 설명 summary = "게시글 단건 조회", description = "id로 특정 게시글을 조회합니다." ) - @GetMapping("/{id}") - public ResponseEntity findById(@PathVariable Long id) { + @GetMapping("/{id}") // URL 경로 변수를 포함한 GET 요청 처리 + public ResponseEntity findById( + @PathVariable Long id // URL 경로의 값을 변수로 받음 + ) { BoardResponse response = boardService.findById(id); return ResponseEntity.ok(response); } - // 게시글 수정 - @Operation( + @Operation( // Swagger 문서용 설명 summary = "게시글 수정", description = "id로 특정 게시글의 제목과 내용을 수정합니다." ) - @("/{id}") - public ResponseEntity update(@PathVariable Long id, - @RequestBody BoardUpdateRequest request) { + @PutMapping("/{id}") // HTTP PUT 요청 처리 + public ResponseEntity update( + @PathVariable Long id, // URL에서 id 값 추출 + @RequestBody BoardUpdateRequest request // 요청 JSON을 객체로 변환 + ) { BoardResponse response = boardService.update(id, request); return ResponseEntity.ok(response); } - // 게시글 삭제 - @Operation( + @Operation( // Swagger 문서용 설명 summary = "게시글 삭제", description = "id로 특정 게시글을 삭제합니다." ) - @("/{id}") - public ResponseEntity delete(@PathVariable Long id) { + @DeleteMapping("/{id}") // HTTP DELETE 요청 처리 + public ResponseEntity delete( + @PathVariable Long id // URL에서 id 값 추출 + ) { boardService.delete(id); - return ResponseEntity.noContent().build(); + return ResponseEntity.noContent().build(); // HTTP 204 No Content 반환 } } \ 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..2baa896 100644 --- a/src/main/java/com/likelion/session/domain/Board.java +++ b/src/main/java/com/likelion/session/domain/Board.java @@ -8,36 +8,36 @@ import java.time.LocalDateTime; -@Getter // getter 메서드 자동 생성 -@Entity // 해당 클래스 DB 테이블로 인식하고 관리 -@Table(name = "boards") -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor +@Getter // 모든 필드에 대한 getter 메서드를 자동 생성 +@Entity // JPA에서 해당 클래스를 DB 테이블로 매핑 +@Table(name = "boards") // DB에서 사용할 테이블 이름을 boards로 지정 +@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자를 protected로 생성 +@AllArgsConstructor // 모든 필드를 포함한 생성자 자동 생성 public class Board { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long ; + @Id // 해당 필드를 기본 키(PK)로 설정 + @GeneratedValue(strategy = GenerationType.IDENTITY) // DB의 auto increment 전략 사용 + private Long id ; // 게시글 제목 - @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,15 +46,15 @@ public Board(String title, String content, String writer) { this.writer = writer; } - @PrePersist + @PrePersist // 엔티티가 처음 DB에 저장되기 직전에 실행되는 메서드 public void prePersist() { - this.createdAt = LocalDateTime.now(); - this.updatedAt = LocalDateTime.now(); + this.createdAt = LocalDateTime.now(); // 생성 시간 자동 설정 + this.updatedAt = LocalDateTime.now(); // 수정 시간도 함께 초기화 } - @PreUpdate + @PreUpdate // 엔티티가 수정되기 직전에 실행되는 메서드 public void preUpdate() { - this.updatedAt = LocalDateTime.now(); + 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..f57bae9 100644 --- a/src/main/java/com/likelion/session/dto/BoardCreateRequest.java +++ b/src/main/java/com/likelion/session/dto/BoardCreateRequest.java @@ -5,13 +5,12 @@ 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..8b56787 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..c7dd0e4 100644 --- a/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java +++ b/src/main/java/com/likelion/session/dto/BoardUpdateRequest.java @@ -7,15 +7,15 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Size; -@Getter -@Setter -@NoArgsConstructor +@Getter // 모든 필드에 대한 getter 메서드 자동 생성 +@Setter // 모든 필드에 대한 setter 메서드 자동 생성 +@NoArgsConstructor // 기본 생성자생성 public class BoardUpdateRequest { - @NotBlank(message = "제목은 필수입니다.") + + @NotBlank(message = "제목은 필수입니다.") // null, 빈 문자열, 공백 모두 허용하지 않음 @Size(max = 100, message = "제목은 100자 이하로 입력해주세요.") private String title; @NotBlank(message = "내용은 필수입니다.") private String content; -} - +} \ No newline at end of file diff --git a/src/main/java/com/likelion/session/service/BoardService.java b/src/main/java/com/likelion/session/service/BoardService.java index 1bc58af..bd9e4ca 100644 --- a/src/main/java/com/likelion/session/service/BoardService.java +++ b/src/main/java/com/likelion/session/service/BoardService.java @@ -18,7 +18,7 @@ @Transactional public class BoardService { - private final ; + private final BoardRepository boardRepository; /* 게시글 생성 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..3700ef1 --- /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/local-session?serverTimezone=Asia/Seoul&characterEncoding=UTF-8 + username: root + password: No3281792003@ + + 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