domain: Article
@EntityListeners(AuditingEntityListener.class)
@Entity
@Getter // 필드값 가져오기 lombok에 있음 getter 필요 없음
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 접근제어자가 prtected인 기본생성자 별도 코드없이 생성 // 생성자 필요없단말
@EntityListeners(AuditingEntityListener.class): 이 어노테이션은 엔티티의 변경을 감지하고 자동으로 관리하는 JPA의 기능을 활성화한다. AuditingEntityListener 클래스는 엔티티의 생성 및 수정 날짜를 자동으로 관리하는데 사용된다.
@Entity: 이 어노테이션은 해당 클래스가 JPA 엔티티임을 나타냄. 이 클래스의 객체는 데이터베이스 테이블에 매핑.
@Getter: 이 어노테이션은 Lombok에서 제공하는 기능으로, 해당 클래스의 모든 필드에 대한 getter 메서드를 자동으로 생성.
@NoArgsConstructor(access = AccessLevel.PROTECTED): 이 어노테이션은 인자 없는 생성자를 자동으로 생성. access 속성을 AccessLevel.PROTECTED로 설정하여 해당 생성자를 protected로 만들어 외부에서 직접 호출하지 못하도록 제한된다. 이는 JPA에서 엔티티를 생성할 때 사용됨.
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false)
private Long id;
@Column(name = "title", nullable = false) // notnull
private String title;
@Column(name = "content", nullable = false)
private String content;
}
@Id: 이 어노테이션은 해당 필드가 엔티티의 주요 식별자(primary key)임을 나타냄. 따라서 데이터베이스 테이블에서 이 필드는 주요 키 역할한다.
@GeneratedValue(strategy = GenerationType.IDENTITY): 이 어노테이션은 주요 키 값이 자동으로 생성되는 방식을 지정. 여기서는 데이터베이스의 자동 증가 기능을 사용하여 주요 키 값을 생성하도록 지정됨. 데이터베이스가 지원하는 자동 증가 기능을 사용하기 위해서는 GenerationType.IDENTITY 전략을 사용한다.
@Column(name = "id", updatable = false): 이 어노테이션은 해당 필드가 데이터베이스의 열과 매핑될 때 열의 속성을 지정. 여기서는 name 속성을 사용하여 데이터베이스의 열 이름을 id로 설정하고, updatable 속성을 false로 설정하여 이 필드가 업데이트되지 않도록 한다. 주요 키 값은 보통 변경되지 않으므로, updatable을 false로 설정하여 보안을 강화하고 실수로 업데이트되는 것을 방지한다.
@CreatedDate // 엔티티가 생성될 때 생성 시간 createAt 에 저장함
@Column(name = "created_at")
private LocalDateTime createdAt;
@CreatedDate 어노테이션은 Spring Data JPA에서 제공하는 기능 중 하나로, 엔티티가 생성될 때 자동으로 현재 시간을 저장하는 역할. 이를 통해 엔티티의 생성 시간을 간편하게 추적할 수 있다.
@Column(name = "created_at") 어노테이션은 이 필드가 데이터베이스의 특정 열과 매핑될 때 열의 속성을 정의한다. 여기서는 데이터베이스의 열 이름을 "created_at"으로 설정했습니다. 이는 실제 데이터베이스에서 엔티티의 생성 시간이 저장될 열을 지정하는 것.
@LastModifiedDate // 앤티티가 마지막에 수정됐을때 시간 updateAt에 저장함
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@LastModifiedDate 어노테이션은 엔티티가 마지막으로 수정될 때 자동으로 현재 시간을 저장.
@Builder // 빌터 패턴으로 객체 생성
public Article(String title, String content) {
this.title = title;
this.content = content;
}
@Builder 어노테이션이 적용된 메서드를 통해 객체를 생성할 수 있다.
public void update(String title, String content) {
this.title = title;
this.content = content;
}
Article 객체의 제목과 내용을 업데이트하는 역할을한다.
dto: AddArticleRequest, ArticleResponse, UpdateArticleRequest
post - AddArticleRequest
get - ArticleResponse
delete - x
put - UpdateArticleRequest
@NoArgsConstructor // 기본생성자
@AllArgsConstructor // 모든 필드값 파라미터로 받는 생성자
@Getter
public class AddArticleRequest {
private String title;
private String content;
public Article toEntity() { // 생성자 사용해 객체 생성 // DTO를 앤티티로 만들어줌
return Article.builder()
.title(title)
.content(content)
.build();
}
}
@NoArgsConstructor: 이 어노테이션은 매개변수 없는 기본 생성자를 자동으로 생성. 이 생성자를 사용하면 객체를 초기화할 때 매개변수를 전달하지 않아도 된다.
@AllArgsConstructor: 이 어노테이션은 모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성한다. 이 생성자를 사용하면 객체를 초기화할 때 모든 필드 값을 한 번에 설정할 수 있다.
public Article toEntity(): 이 메서드는 AddArticleRequest 객체를 Article 객체로 변환하는 역할을 합니다. 이를 통해 DTO(데이터 전송 객체)를 앤티티로 변환할 수 있다. Article 객체를 생성하고 제목과 내용을 설정한 후 반환한다.
@Getter
public class ArticleResponse {
private final String title;
private final String content;
public ArticleResponse(Article article) {
this.title = article.getTitle();
this.content = article.getContent();
}
}
private final String title; 및 private final String content;: 이 두 필드는 블로그 글의 제목과 내용을 나타낸다. final 키워드가 사용되어 이 필드들은 한 번 설정되면 변경할 수 없다.
public ArticleResponse(Article article): 이 생성자는 Article 객체를 받아와서 해당 객체의 제목과 내용을 사용하여 ArticleResponse 객체를 생성한다. 이를 통해 엔티티 객체를 DTO로 변환할 수 있다.
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class UpdateArticleRequest {
private String title;
private String content;
}
public ArticleResponse(Article article): 이 생성자는 Article 객체를 받아와서 해당 객체의 제목과 내용을 사용하여 ArticleResponse 객체를 생성한다. 이를 통해 엔티티 객체를 DTO로 변환할 수 있다.
controller: BlogApiController
@RequiredArgsConstructor
@RestController // HTTP Response Body 에 객체 데이터를 JSON 형식으로 반환하는 컨트롤러
@RequiredArgsConstructor 어노테이션은 Lombok에서 제공하는 기능 중 하나로, 클래스의 필드에 대한 생성자를 자동으로 생성한다.
@RestController 어노테이션은 Spring Framework에서 제공하는 기능 중 하나로, 해당 클래스가 RESTful 웹 서비스의 컨트롤러임을 나타낸다. 즉, HTTP 요청을 처리하고 HTTP 응답을 생성하여 클라이언트에게 전송하는 역할
private final BlogService blogService;
BlogService 타입의 필드를 선언하는 코드. 이 필드는 final로 선언되어 있기 때문에 한 번 초기화되면 다른 값으로 변경할 수 없다. 이러한 구조는 의존성 주입(Dependency Injection)을 통해 외부에서 BlogService 인스턴스를 주입받아 사용할 수 있도록 하는데 일반적으로 사용된다.
// HTTP 메서드가 POST일때 전달받은 URL과 동일하면 매서드로 매핑 // post && url
@PostMapping("/api/articles")
// @RequestBody로 요청 본문 값 매핑
public ResponseEntity<Article> addArticle(@RequestBody AddArticleRequest request) {
// @RequestBody : 응답에 해당하는객체를 매핑 AddArticleRequest에
Article savedArticle = blogService.save(request);
// 요청한 자원이 성공적으로 생성되었으며 저장된 블로그 글 정보를 응답 객체에 담아 전송
return ResponseEntity.status(HttpStatus.CREATED)
.body(savedArticle); // ResponseEntity.status().body() : 응답코드 201, created 응답 후 저장된 객체 반환
}
@PostMapping("/api/articles"): 이 어노테이션은 해당 메서드가 HTTP POST 요청을 처리하고, 요청이 /api/articles 엔드포인트에 도착할 때 실행된다.
public ResponseEntity<Article> addArticle(@RequestBody AddArticleRequest request): 이 메서드는 요청 본문을 받아들이고 (@RequestBody 어노테이션을 통해), AddArticleRequest 객체로 매핑한다. 이 객체에는 새로운 글을 생성하는 데 필요한 정보가 포함된다. 메서드는 ResponseEntity<Article>을 반환하는데, 이는 HTTP 응답을 나타낸다. 반환된 ResponseEntity는 생성된 블로그 글에 대한 정보를 담고 있다.
Article savedArticle = blogService.save(request);: blogService의 save() 메서드를 호출하여 새로운 블로그 글을 생성한다. AddArticleRequest 객체를 사용하여 필요한 정보를 전달한다.
return ResponseEntity.status(HttpStatus.CREATED).body(savedArticle);: 생성된 블로그 글을 응답으로 반환. 응답 코드는 201 (Created)으로 설정되며, 생성된 블로그 글은 응답 본문에 포함된다.
@GetMapping("/api/articles")
public ResponseEntity<List<ArticleResponse>> findAllArticles() {
List<ArticleResponse> articles = blogService.findAll()
.stream()
.map(ArticleResponse::new)
.toList();
return ResponseEntity.ok()
.body(articles);
}
@GetMapping("/api/articles"): 이 어노테이션은 해당 메서드가 HTTP GET 요청을 처리하고, 요청이 /api/articles 엔드포인트에 도착할 때 실행된다.
public ResponseEntity<List<ArticleResponse>> findAllArticles(): 이 메서드는 모든 블로그 글을 조회합니다. 반환 형식은 ResponseEntity<List<ArticleResponse>>로, HTTP 응답을 나타낸다. 응답 본문에는 블로그 글 목록을 포함한 리스트가 들어간다.
List<ArticleResponse> articles = blogService.findAll()...: blogService의 findAll() 메서드를 호출하여 모든 블로그 글을 가져온다. 그 후, map() 함수를 사용하여 각 블로그 글을 ArticleResponse 객체로 변환한다. 이후, toList() 함수를 사용하여 이를 리스트 형태로 변환한다.
return ResponseEntity.ok().body(articles);: 변환된 블로그 글 목록을 응답 본문에 담아 ResponseEntity로 래핑하여 반환한다. ok() 메서드는 HTTP 응답의 상태 코드를 200 (OK)로 설정한다.
@GetMapping("/api/articles/{id}") //HTTP GET 요청을 처리하는 메소드임을 나타냄
public ResponseEntity<ArticleResponse> findArticle(@PathVariable long id) { //@PathVariable : 메소드의 인자가 URL 경로 변수와 연결
Article article = blogService.findById(id);
return ResponseEntity.ok()
.body(new ArticleResponse(article));
}
@GetMapping("/api/articles/{id}"): 이 어노테이션은 해당 메서드가 HTTP GET 요청을 처리하고, 요청이 /api/articles/{id} 엔드포인트에 도착할 때 실행된다는 것을 나타낸다. {id}는 경로 변수로, 이 위치에 실제로 들어오는 값을 사용한다.
public ResponseEntity<ArticleResponse> findArticle(@PathVariable long id): 이 메서드는 URL 경로에서 받아온 id 값을 사용하여 특정 블로그 글을 조회한다. @PathVariable 어노테이션을 통해 URL 경로 변수와 메서드의 매개변수를 연결한다. 반환 형식은 ResponseEntity<ArticleResponse>로, HTTP 응답을 나타낸다. 응답 본문에는 블로그 글을 변환한 ArticleResponse 객체가 포함된다.
Article article = blogService.findById(id);: blogService의 findById() 메서드를 호출하여 해당 id 값을 가진 블로그 글을 조회한다.
return ResponseEntity.ok().body(new ArticleResponse(article));: 조회된 블로그 글을 ArticleResponse 객체로 변환하여 응답 본문에 담아 ResponseEntity로 래핑하여 반환한다. ok() 메서드는 HTTP 응답의 상태 코드를 200 (OK)로 설정한다.
@DeleteMapping("/api/articles/{id}")
public ResponseEntity<Void> deleteArticle(@PathVariable long id) {
blogService.delete(id);
return ResponseEntity.ok()
.build();
}
@DeleteMapping("/api/articles/{id}"): 이 어노테이션은 해당 메서드가 HTTP DELETE 요청을 처리하고, 요청이 /api/articles/{id} 엔드포인트에 도착할 때 실행된다. {id}는 경로 변수로, 이 위치에 실제로 들어오는 값을 사용한다.
public ResponseEntity<Void> deleteArticle(@PathVariable long id): 이 메서드는 URL 경로에서 받아온 id 값을 사용하여 특정 블로그 글을 삭제한다. @PathVariable 어노테이션을 통해 URL 경로 변수와 메서드의 매개변수를 연결한다. 반환 형식은 ResponseEntity<Void>로, HTTP 응답을 나타낸다. 응답 본문이 없으므로 Void를 사용한다.
blogService.delete(id);: blogService의 delete() 메서드를 호출하여 해당 id 값을 가진 블로그 글을 삭제한다.
return ResponseEntity.ok().build();: 요청이 성공적으로 처리되었음을 나타내는 HTTP 상태 코드 200 (OK)와 빈 응답 본문을 함께 반환한다. 이 메서드는 삭제 작업에 대한 응답으로 사용된다.
@PutMapping("/api/articles/{id}")
public ResponseEntity<Article> updateArticle(@PathVariable long id,
@RequestBody UpdateArticleRequest request) {
//request는 업데이트할 게시물의 정보를 담은 UpdateArticleRequest 객체
Article updatedArticle = blogService.update(id, request); // 서비스에 id와 request보냄
return ResponseEntity.ok()
.body(updatedArticle);
}
@PutMapping("/api/articles/{id}"): 이 어노테이션은 해당 메서드가 HTTP PUT 요청을 처리하고, 요청이 /api/articles/{id} 엔드포인트에 도착할 때 실행된다. {id}는 경로 변수로, 이 위치에 실제로 들어오는 값을 사용한다.
public ResponseEntity<Article> updateArticle(@PathVariable long id, @RequestBody UpdateArticleRequest request): 이 메서드는 URL 경로에서 받아온 id 값을 사용하여 특정 블로그 글을 업데이트한다. @PathVariable 어노테이션을 통해 URL 경로 변수와 메서드의 첫 번째 매개변수를 연결한다. @RequestBody 어노테이션을 통해 요청 본문을 받아들이고, 해당 내용을 UpdateArticleRequest 객체로 매핑한다. 반환 형식은 ResponseEntity<Article>로, HTTP 응답을 나타낸다. 응답 본문에는 업데이트된 블로그 글이 포함된다.
Article updatedArticle = blogService.update(id, request);: blogService의 update() 메서드를 호출하여 해당 id 값을 가진 블로그 글을 주어진 요청으로 업데이트한다.
return ResponseEntity.ok().body(updatedArticle);: 업데이트된 블로그 글을 응답 본문에 담아 ResponseEntity로 래핑하여 반환한다. ok() 메서드는 HTTP 응답의 상태 코드를 200 (OK)로 설정한다.
'Spring 공부' 카테고리의 다른 글
spring 프로젝트와 nuxt.js 연동 + mySql (0) | 2024.09.23 |
---|---|
spring - 블로그 예제 service, repository, viewContoroller, templates (0) | 2024.09.23 |
spring 공부 - 앤티티, ORM, JPA, 스프링데이터 JPA (0) | 2024.09.23 |
spring 공부 - 테스트코드 (0) | 2024.09.23 |
spring 공부 - 스프링부트, 계층 (0) | 2024.09.23 |