Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa-test'
testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
}

tasks.named('test') {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/likelion/session/SessionApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ public static void main(String[] args) {
SpringApplication.run(SessionApplication.class, args);
}

}
}
32 changes: 16 additions & 16 deletions src/main/java/com/likelion/session/controller/BoardController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

import java.util.List;

@RestController
@RequestMapping("/boards")
@RequiredArgsConstructor
@RestController // JSON 형태로 객체 데이터를 반환하는 컨트롤러임을 명시
@RequestMapping("/boards") // API 요청 경로의 공통 시작점 설정
@RequiredArgsConstructor // final이 붙은 BoardService 객체를 생성자 주입 방식으로 받아옴 (DI)
public class BoardController {

private final ;
private final BoardService boardService;

/*
게시글 생성
Expand All @@ -32,58 +32,58 @@ public class BoardController {
-> 결과 반환
-> JSON 응답
*/
@Operation(
@Operation( // Swagger: API 문서에 제목과 상세 설명을 표시
summary = "게시글 생성",
description = "새로운 게시글을 생성합니다."
)
@
@PostMapping // HTTP POST 요청 처리: 주로 데이터를 생성할 때 사용
public ResponseEntity<BoardResponse> create(@RequestBody BoardCreateRequest request) {
BoardResponse response = boardService.create(request);
return ResponseEntity.ok(response);
return ResponseEntity.ok(response); // 성공 응답(200 OK)과 함께 데이터 반환
}

// 게시글 전체 조회
@Operation(
@Operation( // API 기능 요약
summary = "게시글 전체 조회",
description = "등록된 모든 게시글을 조회합니다."
)
@
@GetMapping // HTTP GET 요청 처리: 주로 데이터를 조회할 때 사용
public ResponseEntity<List<BoardResponse>> findAll() {
List<BoardResponse> response = boardService.findAll();
return ResponseEntity.ok(response);
}

// 게시글 단건 조회
@Operation(
@Operation( // API 기능 요약
summary = "게시글 단건 조회",
description = "id로 특정 게시글을 조회합니다."
)
@GetMapping("/{id}")
@GetMapping("/{id}") // 경로에 포함된 {id} 값을 변수로 사용함
public ResponseEntity<BoardResponse> findById(@PathVariable Long id) {
BoardResponse response = boardService.findById(id);
return ResponseEntity.ok(response);
}

// 게시글 수정
@Operation(
@Operation( // API 기능 요약
summary = "게시글 수정",
description = "id로 특정 게시글의 제목과 내용을 수정합니다."
)
@("/{id}")
@PutMapping("/{id}") // HTTP PUT 요청 처리: 주로 전체 데이터를 수정할 때 사용
public ResponseEntity<BoardResponse> update(@PathVariable Long id,
@RequestBody BoardUpdateRequest request) {
BoardResponse response = boardService.update(id, request);
return ResponseEntity.ok(response);
}

// 게시글 삭제
@Operation(
@Operation( // API 기능 요약
summary = "게시글 삭제",
description = "id로 특정 게시글을 삭제합니다."
)
@("/{id}")
@DeleteMapping("/{id}") // HTTP DELETE 요청 처리: 데이터를 삭제할 때 사용
public ResponseEntity<Void> delete(@PathVariable Long id) {
boardService.delete(id);
return ResponseEntity.noContent().build();
return ResponseEntity.noContent().build(); // 삭제 성공 시 보낼 데이터가 없으므로 204 No Content 반환
}
}
49 changes: 24 additions & 25 deletions src/main/java/com/likelion/session/domain/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,54 @@

@Getter // getter 메서드 자동 생성
@Entity // 해당 클래스 DB 테이블로 인식하고 관리
@Table(name = "boards")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@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) // PK 값을 DB가 자동으로 증가시켜줌 (MySQL 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) {
public Board(String title, String content, String writer) { // 새로운 게시글 객체를 처음 만들 때 사용
this.title = title;
this.content = content;
this.writer = writer;
}

@PrePersist
@PrePersist // 데이터가 처음 DB에 저장(persist)되기 직전에 자동으로 실행됨
public void prePersist() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
this.createdAt = LocalDateTime.now(); // 생성 시간 기록
this.updatedAt = LocalDateTime.now(); // 수정 시간도 생성 시간과 동일하게 초기화
}

@PreUpdate
@PreUpdate // 데이터가 수정(update)되기 직전에 자동으로 실행됨
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
}

} // 수정 시간을 현재 시간으로 갱신

public void update(String title, String content) {
// 게시글 수정을 위한 메서드
public void update(String title, String content) { // 이미 만들어진 게시글의 내용을 바꿀 때 사용
this.title = title;
this.content = content;
}
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/com/likelion/session/dto/BoardCreateRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Getter // Lombok: 데이터를 꺼내오기 위한 getter 메서드 자동 생성
@Setter // Lombok: 데이터를 필드에 넣어주기 위한 setter 메서드 자동 생성
@NoArgsConstructor // Lombok: 파라미터가 없는 기본 생성자 생성
@AllArgsConstructor // Lombok: 모든 필드를 파라미터로 받는 생성자 생성
public class BoardCreateRequest {
// 넘겨주고 싶은 정보: 제목(title), 내용(content), 작성자(writer)
private String ;
private String ;
private String ;
private String title;
private String content;
private String writer;
}
6 changes: 3 additions & 3 deletions src/main/java/com/likelion/session/dto/BoardResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

import java.time.LocalDateTime;

@Getter
@AllArgsConstructor
@Builder
@Getter // Lombok: 응답 데이터를 꺼내 JSON으로 변환하기 위해 필요함
@AllArgsConstructor // Lombok: 모든 데이터를 담아 객체를 만들기 위한 생성자 생성
@Builder // Lombok: 빌더 패턴을 사용하여 객체 생성을 유연하고 가독성 있게 해줌
public class BoardResponse {

// 돌려주고 싶은 응답: id, title, content, writer, createdAt, updatedAt
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/com/likelion/session/dto/BoardUpdateRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

@Getter
@Setter
@NoArgsConstructor
@Getter // Lombok: 데이터 조회를 위한 getter 메서드 생성
@Setter // Lombok: 데이터 수정을 위한 setter 메서드 생성
@NoArgsConstructor // Lombok: 기본 생성자 생성
public class BoardUpdateRequest {
@NotBlank(message = "제목은 필수입니다.")
@Size(max = 100, message = "제목은 100자 이하로 입력해주세요.")
@NotBlank(message = "제목은 필수입니다.") // Validation: 빈 값, 공백만 있는 값을 허용하지 않음
@Size(max = 100, message = "제목은 100자 이하로 입력해주세요.") // Validation: 최대 100자까지만 허용
private String title;

@NotBlank(message = "내용은 필수입니다.")
@NotBlank(message = "내용은 필수입니다.") // Validation: 내용이 비어있는지 검사함
private String content;
}

32 changes: 16 additions & 16 deletions src/main/java/com/likelion/session/service/BoardService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
@Slf4j // Lombok: 로깅(로그 출력)을 위한 객체를 생성함
@Service // 이 클래스가 비즈니스 로직을 담당하는 서비스 레이어임을 Spring에 알림
@RequiredArgsConstructor // final이 붙은 필드(boardRepository)에 대한 생성자를 자동으로 생성하여 의존성 주입(DI)을 해줌
@Transactional // DB 작업 도중 에러가 나면 모든 작업을 이전으로 롤백(Rollback)하여 데이터 일관성을 유지함
public class BoardService {

private final ;
private final BoardRepository boardRepository;

/*
게시글 생성
Expand All @@ -27,16 +27,16 @@ public class BoardService {
- Repository를 통해 DB에 저장
- 저장된 결과를 Response DTO로 변환해서 반환
*/
public BoardResponse create(BoardCreateRequest request) {
public BoardResponse create(BoardCreateRequest request) { // DTO를 엔티티(Entity)로 변환하는 것
Board board = new Board(
request.getTitle(),
request.getContent(),
request.getWriter()
);

Board savedBoard = boardRepository.save(board);
Board savedBoard = boardRepository.save(board); // Repository를 통해 DB에 저장

return BoardResponse.builder()
return BoardResponse.builder() // 저장된 엔티티 정보를 DTO에 담아 반환
.id(savedBoard.getId())
.title(savedBoard.getTitle())
.content(savedBoard.getContent())
Expand All @@ -51,27 +51,27 @@ public BoardResponse create(BoardCreateRequest request) {
- DB에 있는 모든 게시글을 가져옴
- Entity 리스트를 Response DTO 리스트로 변환
*/
@Transactional(readOnly = true)
@Transactional(readOnly = true) // 조회 전용 설정으로 성능 최적화에 도움을 줌
public List<BoardResponse> findAll() {
return boardRepository.findAll()
.stream()
.map(board -> BoardResponse.builder()
.map(board -> BoardResponse.builder() // 각 엔티티 객체를 DTO 객체로 변환 (Mapping)
.id(board.getId())
.title(board.getTitle())
.content(board.getContent())
.writer(board.getWriter())
.createdAt(board.getCreatedAt())
.updatedAt(board.getUpdatedAt())
.build())
.toList();
.toList(); // 리스트 형태로 반환
}

/*
게시글 단건 조회
- id로 게시글 조회
- 없으면 예외 발생
*/
@Transactional(readOnly = true)
@Transactional(readOnly = true) // 읽기 전용 트랜잭션
public BoardResponse findById(Long id) {
Board board = boardRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));
Expand All @@ -92,11 +92,11 @@ public BoardResponse findById(Long id) {
- 엔티티의 update 메서드로 값 변경
- JPA 변경 감지로 update 반영
*/
public BoardResponse update(Long id, BoardUpdateRequest request) {
public BoardResponse update(Long id, BoardUpdateRequest request) { // 게시글 수정 메서드
Board board = boardRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));

board.update(request.getTitle(), request.getContent());
board.update(request.getTitle(), request.getContent()); // 엔티티 객체의 정보를 수정함

return BoardResponse.builder()
.id(board.getId())
Expand All @@ -113,10 +113,10 @@ public BoardResponse update(Long id, BoardUpdateRequest request) {
- id로 게시글을 찾고
- 있으면 삭제
*/
public void delete(Long id) {
public void delete(Long id) { // 게시글 삭제 메서드
Board board = boardRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));

boardRepository.delete(board);
boardRepository.delete(board); // Repository를 통해 DB에서 삭제함
}
}