[TIL 29] 간단한 게시판 구현하기_Spring#5

돗치·2024년 3월 31일

Spring으로 간단한 게시판 구현해보기 #마지막

@Transient
    private List<ReplyEntity> replyList = List.of();

@Transient@OneToMany(mappedBy="post")로 바꾼다.

PostEntity로 가서 postId

    @ManyToOne
    @ToString.Exclude
    @JsonIgnore
    private PostEntity post;

로 바꿔준다.

PostService에서

@Service
@RequiredArgsConstructor
public class ReplyService {

    private final ReplyRepository replyRepository;
    private final PostRepository postRepository;

    public ReplyEntity create(
            ReplyRequest replyRequest
    ){
        var postEntity = postRepository.findById(replyRequest.getPostId()).get();
        
        var entity = ReplyEntity.builder()
                .post(postEntity)

로 바꾸려했지만 var postEntity = postRepository.findById(replyRequest.getPostId()).get();처럼 원래는 바로 get하면 안된다. 그래서 Post에 넣어주고 예외를 던지자.

@Service
@RequiredArgsConstructor
public class ReplyService {

    private final ReplyRepository replyRepository;
    private final PostRepository postRepository;

    public ReplyEntity create(
            ReplyRequest replyRequest
    ){
        var optionalPostEntity = postRepository.findById(replyRequest.getPostId());
        if (optionalPostEntity.isEmpty()){
            throw new RuntimeException("게시물이 존재 하지 않습니다.: " +replyRequest.getPostId());
        }
        var entity = ReplyEntity.builder()
                .post(optionalPostEntity.get())
                .userName(replyRequest.getUserName())
                .password(replyRequest.getPassword())
                .status("REGISTERED")
                .title(replyRequest.getTitle())
                .content(replyRequest.getContent())
                .repliedAt(LocalDateTime.of(2024, 3, 17, 8, 34))
                .build();

        return replyRepository.save(entity);
    }

API TESTER에서 POST로 http://localhost:8080/api/post/view 에 SEND하면

이러면 PostService에 있는

                    //답글
                    var replyList = replyService.findAllByPostId(it.getId());
                    it.setReplyList(replyList);

를 지워도 된다.
이제는 PostEntity 안에 @OneToMany라는 annotation을 통해 reply list를 가져오도록 돼 있기 때문이다.

하지만 여기서 문제가 있다.

delete한 글들이 status가 바꼈을 뿐 여기서 계속 보인다.

BoardEntity에서 private List<PostEntity> postList = List.of();
@Where(clause = "status = 'REGISTERED'")을 달아준다. status가 registered인 것만 불러오겠다는 것이다.

    @OneToMany(mappedBy = "board")
    @Where(clause = "status = 'REGISTERED'")
    private List<PostEntity> postList = List.of();

1번 게시판을 불러왔을 때 status가 registered인 것만 나온다.
http://localhost:8080/api/board/id/1

글을 많이 만들어보자

최신순으로 나오지 않고 쿼리가 두번 실행되는걸 로그에서 볼 수 있다.
만약 건수가 많아지게 되면 성능에 영향을 미칠 수 있다.

    @OneToMany(mappedBy = "board")
    @Where(clause = "status = 'REGISTERED'")
    @Builder.Default
    @OrderBy("id DESC")
    private List<PostEntity> postList = List.of();

로 바꿔보자

지워진 글이 보이지 않고 글도 최신순으로 나오게 됐다.

페이징 처리

이제 페이징 처리를 해보자

PostController에서

    @GetMapping("/all")
    public List<PostEntity> list(
        @PageableDefault(page = 0,size = 10)
        Pageable pageable
    ){
        return postService.all(pageable);
    }

으로 바꾸고 all에 ctrl 좌클릭해서 이동하자
Api클래스와 Pagination클래스를 만들자

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class Api<T> {
    private T body;
    private Pagination pagination;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString

public class Pagination {
    private Integer page;
    private Integer size;
    private Integer currentElements;
    private Integer totalPage;
    private Integer totalElements;
}
    public Api<List<PostEntity>> all(Pageable pageable) {
        var list = postRepository.findAll(pageable);
        var pagination = Pagination
                .builder()
                .page(list.getNumber())
                .size(list.getSize())
                .currentElements(list.getNumberOfElements())
                .totalPage(list.getTotalPages())
                .build()
                ;

        var response = Api.<List<PostEntity>>builder()
                .body(list.toList())
                .pagination(pagination)
                .build();
        return response;
    }

PostController로 돌아와서 Api<>로 묶어주자

    @GetMapping("/all")
    public Api<List<PostEntity>> list(
        @PageableDefault(page = 0,size = 10)
        Pageable pageable
    ){
        return postService.all(pageable);
    }

GET으로 http://localhost:8080/api/post/all?page=0&size=5 에 SEND하면 아래 처럼 나온다

Page를 3으로 하면 이렇게 나온다.

하지만 또 페이징처리를 하니 최신순으로 나오지 않는다.

    @GetMapping("/all")
    public Api<List<PostEntity>> list(
        @PageableDefault(page = 0,size = 10, sort = "id", direction = Sort.Direction.DESC)
        Pageable pageable
    ){
        return postService.all(pageable);
    }

@PageableDefault에 direction = Sort.Direction.DESC를 추가해주고 sort를 "id"로 지정하겠다고 해준다.

이제 최신순으로 나오게 된다.

0개의 댓글