1. 게시판 CRUD 만들기
2. 게시판 API 명세서
3. 게시판 Sequence diagram
(틀릴수도 있음)
@RequiredArgsConstructor
@RequestMapping("/posts")
@Controller
@Slf4j
public class PostApiController {
private final PostService postService;
//게시글 form 가져오기
@PreAuthorize("isAuthenticated()")
@GetMapping("/form")
public String postForm(ModelMap map) {
map.addAttribute("formStatus", FormStatus.CREATE);
return "posts/form";
}
@PreAuthorize("isAuthenticated()")
@PostMapping
public ResponseEntity<Long> newPost(@AuthenticationPrincipal PostPrincipal postPrincipal, @RequestBody PostsRequest request) {
Long result = postService.savePost(request.toDto(postPrincipal.toDto()));
return ResponseEntity.status(HttpStatus.CREATED)
.body(result);
}
// 게시글 업데이트 form 가져오기
@PreAuthorize("isAuthenticated()")
@GetMapping("/{postId}/update")
public String updatePostForm(@PathVariable Long postId, ModelMap map) {
PostsResponse post = PostsResponse.from(postService.getPost(postId));
map.addAttribute("post", post);
map.addAttribute("formStatus", FormStatus.UPDATE);
return "posts/updatePostForm";
}
@PreAuthorize("isAuthenticated()")
@PostMapping("/{postId}/update")
public String updatePost(@PathVariable Long postId, @AuthenticationPrincipal PostPrincipal postPrincipal,
@ModelAttribute PostsRequest postsRequest) {
postService.updatePost(postId, postsRequest.toDto(postPrincipal.toDto()));
return "fragments/main";
}
@DeleteMapping("/{postId}/delete")
public String deletePost(@PathVariable Long postId, @AuthenticationPrincipal PostPrincipal postPrincipal) {
// 삭제 로직 수행
postService.deletePost(postId, postPrincipal.email());
return "redirect:/";
}
}
회원가입 해야 게시글이 작성가능해지며 회원가입 안할시 글쓰기 버튼 누르면 회원가입 페이지로 이동하게 했습니다.
4. Service
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PostService {
private final PostRepository postRepository;
private final MemberRepository memberRepository;
//조회수
@Transactional
public Integer updateView(Long post_no) {return postRepository.updateView(post_no);}
// 검색
@Transactional
public Page<PostDto> searchPosts(String searchKeyword, Pageable pageable) {
if (searchKeyword == null || searchKeyword.isBlank()) {
return postRepository.findAll(pageable).map(PostDto::from);
}
Page<PostDto> titleResults = postRepository.findByTitleContaining(searchKeyword, pageable).map(PostDto::from);
Page<PostDto> contentResults = postRepository.findByContentContaining(searchKeyword, pageable).map(PostDto::from);
Page<PostDto> nicknameResults = postRepository.findByMember_NicknameContaining(searchKeyword, pageable).map(PostDto::from);
List<PostDto> mergedResults = Stream.concat(
Stream.concat(titleResults.getContent().stream(), contentResults.getContent().stream()),
nicknameResults.getContent().stream()
)
.distinct() // 중복 항목 제거
.collect(Collectors.toList());
// 마지막으로, 페이지로 변환하여 반환합니다.
int start = (int) pageable.getOffset();
int end = Math.min((start + pageable.getPageSize()), mergedResults.size());
return new PageImpl<>(mergedResults.subList(start, end), pageable, mergedResults.size());
}
public Page<PostDto> AllPost(Pageable pageable){
return postRepository.findAll(pageable).map(PostDto::from);
}
public PostWithCommentDto getPostWithComments(Long postId){
return postRepository.findById(postId)
.map(PostWithCommentDto::from)
.orElseThrow(() -> new EntityNotFoundException("게시글이 없습니다 -postId" + postId));
}
public PostDto getPost(Long postId) {
return postRepository.findById(postId)
.map(PostDto::from)
.orElseThrow(() -> new EntityNotFoundException("게시글이 없습니다 - postId: " + postId));
}
@Transactional
public Long savePost(PostDto dto) { //게시물 생성
Member member = memberRepository.getReferenceById(dto.memberDto().email());
Post post = dto.toEntity(member);
postRepository.save(post);
return post.getId();
}
@Transactional
public long updatePost(Long postId, PostDto dto) {
Post post = postRepository.findById(postId).orElseThrow(() -> new IllegalArgumentException("해당게시글은 없습니다. id" + postId));
Member member = memberRepository.getReferenceById(dto.memberDto().email());
if(post.getMember().equals(member)){
if (dto.title() != null){ post.setTitle(dto.title());}
if (dto.content() != null){post.setContent(dto.content());}
postRepository.flush();
}
postRepository.save(post);
return post.getId();
}
@Transactional
public void deletePost(Long postNo, String email) {
postRepository.getReferenceById(postNo);
postRepository.deleteByIdAndMember_email(postNo, email);
}
public long getPostCount() {
return postRepository.count();
}
}
4. 게시판 CREATE
게시판이 작성이 되면 게시글이 제목과 본문으로 저장 메인페이지에 조회순으로 정렬이 된상태에서 메인페이지에 나타난다.
4. mysql DB에 저장이 된다.
5. 게시판 update
수정 버튼을 누르면 수정 form를 가져옵니다.
수정버튼 누르면 수정 폼을 가져오면서 게시글 수정이 가능해집니다.
6. 게시판 삭제
삭제 버튼을 누르면 팝업이 뜬상태에서 DB에서 삭제 됩니다.
https://github.com/nodwon/OhouseV1
GitHub - nodwon/OhouseV1: 지금까지 공부한것을 기반으로 포트폴리오 제작
지금까지 공부한것을 기반으로 포트폴리오 제작. Contribute to nodwon/OhouseV1 development by creating an account on GitHub.
github.com
'포트폴리오 > ohouseClone' 카테고리의 다른 글
8. 메인페이지 & 마이페이지 제작(Card) thymeleaf (0) | 2023.11.01 |
---|---|
7. 게시판 소셜로그인 만들기(google, naver, kakao)-spring (1) | 2023.11.01 |
5. SpringSecurity 설정 및 customlogin페이지 제작 (0) | 2023.09.05 |
4. 게시판 작성 front & member api (0) | 2023.09.05 |
3. 커뮤니티 게시판 서비스 api 개발 & 메인 페이지 (0) | 2023.08.19 |