🌿SPRING/🌱연습[SPRING]

[SPRING] 좋아요 토글 만들기 (0,1)

디카페인라떼 2022. 9. 22. 22:34

계속 미뤄두던 좋아요 토글 ㅎㅎㅎ 사실은 다른 프로젝트하면서 구현은 했으나(boolean) 버튼이름이 좋아요가 아닐 뿐이었다...

어째든 좋아요 토글을 예전에 프로젝트 할 때는 (0,1) 방식으로 구현했던 게 있어서 그걸 한번 해보았다. 많이 어렵지는 않으나 역시 또 까먹을까봐 정리해두기....^^


1. Entity 설정
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class LikePost {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @JoinColumn(name = "member_id", nullable = false)
  @ManyToOne(fetch = FetchType.LAZY)
  private Member member;

  @JoinColumn(name = "posting_Id", nullable = false)
  @ManyToOne(fetch = FetchType.LAZY)
  private Posting posting;

}
  • 게시글 좋아요만 할거여서 하나만 해줬다!
    • 만약 게시글 좋아요 / 댓글 좋아요 / 대댓글 좋아요 모두 따로 있다면 엔티티를 따로 지정해 주어야 한다! 
  • 이번에는 Builder 방식 .. 

 

2.Dto
  • LikePostingResoponseDto
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LikePostingResponseDto {

  private Long id;
  private String title;
  private String content;
  private String author;
  private Long likes;
  private LocalDateTime createdAt;
  private LocalDateTime modifiedAt;
  private List<CommentResponseDto> commentResponseDtoList;


}

👉 이거는 근데... 응답 값에 그냥 String만 나가도 될 것 같아서..ㅎㅎ 있어도 되고 없어도 되고.. (결국 안씀^^..)

 

🚨 원래 있던 게시글 에 좋아요가 추가 된거라 원래 있던 Posting에 필드를 추가해주었다.

  • Posting Entity
@Column(nullable = false)
private Long likes;


  //게시글 작성시
  public Posting(PostingRequestDto postingRequestDto, Member member, String postImg) {
    this.title = postingRequestDto.getTitle();
    this.content = postingRequestDto.getContent();
    this.member = member;
    this.postImg = postImg;
    this.likes = 0L; // 처음 작성시에는 무조건 0으로 (작성자가 좋아요를 누른 상태가 아님)
  }

  //게시글 좋아요 눌렀을 때
  public void updateLikes(Long likes) {
    this.likes = likes;
  }
  • PostingResponseDto
public PostingResponseDto(Posting posting) {
  this.id = posting.getId();
  this.title = posting.getTitle();
  this.content = posting.getContent();
  this.postImg = posting.getPostImg();
  this.likes = posting.getLikes(); //응답값에도 좋아요여부를 보여줘야지..
  this.author = posting.getMember().getNickname();
  this.member = new MemberResponseDto(posting.getMember());
  this.createdAt = posting.getCreatedAt();
  this.modifiedAt = posting.getModifiedAt();
}

 

3.Repository
  • 마찬가지로 로직을 짜면서 계속 추가 되었다 ㅎㅎ
public interface LikePostingRepository extends JpaRepository<LikePost, Long> {

  Long countAllByPosting(Posting posting);

  LikePost findByPostingAndMember(Posting posting, Member member);
}

 

4. Service
  • 아예 좋아요 Service를 따로 따서 했당 
@Override
@Transactional
public ResponseDto<String> togglePostLike(Long id, HttpServletRequest request) {
 //권한 확인 부분..
  if (null == request.getHeader("Refresh-Token")) {
    throw new CustomException(ErrorCode.MEMBER_NOT_FOUND);
  }

  if (null == request.getHeader("Authorization")) {
    throw new CustomException(ErrorCode.MEMBER_NOT_FOUND);
  }

  Member member = validateMember(request);
  if (null == member) {
    throw new CustomException(ErrorCode.INVALID_TOKEN);
  }
  
 //유효한 게시글인지 확인
  Posting post = postingService.findById(id);
  if (null == post) {
    throw new CustomException(ErrorCode.POSTING_ID_NOT_FOUND);
  }

 //선택한 게시글과 작성자로 좋아요 하려는 게시글의 like부분을 찾아서
  LikePost checkLike = likePostingRepository.findByPostingAndMember(post, member);
  //null이면 
  if (checkLike == null) {
    // like 등록
    LikePost likePost = LikePost.builder()
        .member(member)
        .posting(post)
        .build();
    //DB에 저장    
    likePostingRepository.save(likePost);
  } else { //null이 아닐 경우 => 이미 좋아요 함
    //like 취소
    likePostingRepository.deleteById(checkLike.getId());
  }

  // 해당 게시물 likes 업데이트
  Long likes = likePostingRepository.countAllByPosting(post);
  post.updateLikes(likes);

  if (checkLike == null) {
    return new ResponseDto("like post success");
  } else {
    return new ResponseDto("Unlike post");
  }
}

 

5.Controller
//게시글 좋아요
@PostMapping("/api/auth/like/post/{postId}")
public ResponseDto<?> togglePostLike(@PathVariable Long postId, HttpServletRequest request) {
  return likeService.togglePostLike(postId, request);
}
  • 토글이라... 좋아요 안된 상태 (0) -> (1)로 변경 / 좋아요 상태 (1)->(0)으로 간단하게 변경가능하다

Postman 결과
  • 게시글 작성시

  • likes : 0

 

  • 게시글 좋아요

👉 게시글 상세조회

  • 좋아요 취소

👉게시글 상세 조회


 

🚨좋아요 갯수는 아직 구현 안했다... 일단 사용자가 해당 게시물에 대해 좋아요 여부만 1,0 으로 확인 가능..

👉 다음 포스팅은 같은 토글인데 0,1 값이 아닌 boolean으로 확인가능한 것으로! 방법은 근데 비슷하다 ㅎ

🤦‍♀️ 조금더 공부해서 JPA Native Query로 구현해보고 싶은데 어렵다 ..^^