코드 그라데이션
입문 과제 라이브코딩 (2) 완성한 코드 본문
Entity
Post
@Entity
@Getter
@NoArgsConstructor
public class Post extends TimeStamped {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
private String writer;
private String password;
private String content;
// public Board() {} // 기본 생성자는 반드시 있어야 한다.
public Post(String title, String writer, String password, String content) {
this.title = title;
this.writer = writer;
this.password = password;
this.content = content;
} // 게시판 생성 - 제목, 글쓴이, 비밀번호, 내용 => 이렇게 네 개의 요소
public void update(String title, String writer, String content) {
this.title = title;
this.writer = writer;
this.content = content;
} // 게시글 업데이트(수정) 로직 / 제목, 작성자명, 작성 내용을 수정
//비밀번호 검증 로직
public boolean isValidPassword(String inputPassword) {
if (inputPassword.equals(this.password)) {
return true;
} else {
return false;
}
}
}
TimeStamped
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class TimeStamped {
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime modifiedAt;
}
DTO
PostResponse
@Getter
@NoArgsConstructor
public class PostResponse {
private String title;
private String writer;
private String content;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
public PostResponse(Post post) {
this.title = post.getTitle();
this.writer = post.getWriter();
this.content = post.getContent();
this.createdAt = post.getCreatedAt();
this.modifiedAt = post.getModifiedAt();
}
}
CreatePostRequest
@Getter
@NoArgsConstructor // 기본생성자 생성과 동일
public class CreatePostRequest {
private String title;
private String writer;
private String password;
private String content;
//@Getter와 @NoArgsConstructor가 합쳐져서 @Setter 없어도 값이 title, writer, password, content에 꽂힌다.
//public CreateBoardRequest() {} => NoArgsConstructor로 치환.
public CreatePostRequest(String title, String writer, String password, String content) {
this.title = title;
this.writer = writer;
this.password = password;
this.content = content;
}
}
UpdatePostRequest
@Getter
@NoArgsConstructor
public class UpdatePostRequest {
private String title;
private String writer;
private String content;
private String password;
public UpdatePostRequest(String title, String writer, String content, String password) {
this.title = title;
this.writer = writer;
this.content = content;
this.password = password;
}
}
DeletePostRequest
@Getter
@NoArgsConstructor
public class DeletePostRequest {
private String password;
public DeletePostRequest(String password) {
this.password = password;
}
}
Controller
PostController
@RestController
@RequiredArgsConstructor
public class PostController {
private final PostService postService;
// 게시물 생성
@PostMapping("/api/posts")
//CreateBoardRequest 의 값을 전달 받음.
public void createPost(@RequestBody CreatePostRequest createPostRequest) {
postService.createPost(createPostRequest);
}
// 전체 게시물 조회
@GetMapping("/api/posts")
public List<PostResponse> getPostList() {
return postService.getPostList();
}
// 게시물 1개 조회
///api/posts/1
@GetMapping("/api/posts/{postId}")
public PostResponse getPost(@PathVariable Long postId) {
return postService.getPost(postId);
}
// 게시물 1개 수정
@PutMapping("/api/posts/{postId}")
public void updatePost(@PathVariable Long postId, @RequestBody UpdatePostRequest updatePostRequest) {
postService.updatePost(postId, updatePostRequest);
}
// 게시물 삭제
@DeleteMapping("/api/posts/{postId}")
public void deletePost(@PathVariable Long postId, @RequestBody DeletePostRequest deletePostRequest) {
postService.deletePost(postId, deletePostRequest);
}
}
Service
PostService
@Service // 이게 없으면 서버가 안 뜬다.
public class PostService {
private final PostRepository postRepository;
// Repository를 상속받은 이 인터페이스는 DB처럼 동작한다. DB에게 시킬 때 얘한테 시키면 된다.
public PostService(PostRepository postRepository) {
this.postRepository = postRepository;
}
// 게시글 전체 조회
@Transactional
public List<PostResponse> getPostList() {
// 작성 날짜 기준 내림차순으로 정리하기 ==> 게시물 작성 최신순으로 정렬해 내놓으란 뜻.
List<Post> postList = postRepository.findAllByOrderByCreatedAtDesc();
List<PostResponse> postResponseList = new ArrayList<>();
for (Post post : postList) {
postResponseList.add(new PostResponse((post)));
}
return postResponseList;
}
@Transactional
// 게시글 생성 로직
public void createPost(CreatePostRequest createPostRequest) {
Post post = new Post(createPostRequest.getTitle(), createPostRequest.getWriter(), createPostRequest.getPassword(), createPostRequest.getContent());
postRepository.save(post);
}
@Transactional
// 게시글 조회 로직
public PostResponse getPost(Long postId) {
Post post = postRepository.findById(postId).orElseThrow(() -> new IllegalArgumentException("id 없음"));
return new PostResponse(post);
}
// 게시글 수정 로직
@Transactional
public void updatePost(Long postId, UpdatePostRequest updatePostRequest) {
Post postSaved = postRepository.findById(postId).orElseThrow(() -> new IllegalArgumentException("id 없음"));
// boardSaved.update(updateBoardRequest.getTitle(), updateBoardRequest.getWriter(), updateBoardRequest.getContent());
// 추가요건 : 수정요청 시 수정 데이터와 비밀번호를 함께 보내서 서버에서 비밀번호 일치 여부 확인 후 업데이트 해라.
// 이게 앞서 넣어놓은(Board 에다가) 비밀번호 유효성 검사.
if (postSaved.isValidPassword(updatePostRequest.getPassword())) {
postSaved.update(updatePostRequest.getTitle(), updatePostRequest.getWriter(), updatePostRequest.getContent());
postRepository.save(postSaved);
} else {
throw new IllegalArgumentException("패스워드가 틀렸습니다!");
}
}
// 게시글 삭제 로직
@Transactional
public void deletePost(Long postId, DeletePostRequest deletePostRequest) {
Post postDelete = postRepository.findById(postId).orElseThrow(() -> new IllegalArgumentException("id 없음"));
String password = deletePostRequest.getPassword();
if (postDelete.isValidPassword(password)) {
postRepository.delete(postDelete); //delete는 JPA에서 직접 제공 => 쿼리 직접 날려준다
System.out.println("삭제에 성공했습니다.");
} else {
throw new IllegalArgumentException("패스워드가 다릅니다!");
}
}
}
Repository
PostRepository
public interface PostRepository extends JpaRepository<Post, Long> {
List<Post> findAllByOrderByCreatedAtDesc();
}
728x90
'Spring > CRUD 연습' 카테고리의 다른 글
입문 과제 라이브코딩 (3) 자세한 설명 추가 (0) | 2023.02.04 |
---|---|
입문 과제 라이브코딩 (1) 과제 정보 (0) | 2023.02.04 |
Comments