좋아요를 복합키 composite key 를 사용해서 구현했습니다. 

 

Controller

@PostMapping("/api/post/like/{postid}")
public ResponseEntity<SuccessResponse<ResponsePostLikeDto>> postLike(@PathVariable Long postid, @AuthenticationPrincipal CustomUserDetails userDetails){

    return SuccessResponse.toResponseEntity(POST_LIKE, postLikeService.postLike(postid, userDetails.getMember()));
}
  • 좋아요하려는 post의 Id와 멤버 정보를 가져옵니다.

 

Service

public ResponsePostLikeDto postLike(Long postId, Member member){
    Post postliked = postRepository.findById(postId)
            .orElseThrow(()-> new NotFoundException(LIKE, SERVICE, POST_NOT_FOUND)
            );
    PostLikeCompositeKey postLikeCompositeKey
            = new PostLikeCompositeKey(member.getId(), postliked.getId());
    boolean likecheck;

    if(postLikeRepository.findById(postLikeCompositeKey).isPresent()){
        postLikeRepository.deleteById(postLikeCompositeKey);
        postliked.disLike();
        postRepository.save(postliked);
        likecheck = false;

        return new ResponsePostLikeDto(likecheck, postliked.getLikeCount());
    }

    postLikeRepository.save(new PostLike(postLikeCompositeKey, member,postliked));
    likecheck=true;
    postliked.likeCount();
    postRepository.save(postliked);

    return new ResponsePostLikeDto(likecheck, postliked.getLikeCount());

}
  • 좋아요한 id 가 있으면 취소하고 좋아요 수를 1 감소시키고, 없으면 좋아요 아이디를 생성하고 좋아요 수를 올려줍니다.
  • Boolean 타입 likecheck을 반환해서 프론트에 보내줍니다. 프론트에서 확인하고 좋아요 아이콘 상태를 변경하는 데 사용합니다.
  • post에 likeCount 를 위한 메서드를 넣어줍니다.
public void likeCount(){
    this.likeCount++;
}

public void disLike(){
    this.likeCount--;
}

 

Composite Key

@Embeddable
@NoArgsConstructor
public class PostLikeCompositeKey implements Serializable {

    @Column(nullable = false)
    private Long memberId;

    @Column(nullable = false)
    private Long postLikedId;

    public PostLikeCompositeKey(Long memberId, Long postLikedId){
        this.memberId = memberId;
        this.postLikedId = postLikedId;
    }
}
  • 복합키는 memberId와 postLikedId를 가집니다. 좋아요한 postId 입니다.

 

PostLike

@Entity
@NoArgsConstructor
@Getter
public class PostLike {

    @EmbeddedId
    private PostLikeCompositeKey id;

    @MapsId("memberId")
    @ManyToOne(fetch = FetchType.LAZY)
    private Member member;

    @MapsId("postLikedId")
    @ManyToOne(fetch = FetchType.LAZY)
    private Post postLiked;

    public PostLike(PostLikeCompositeKey id, Member member, Post postLiked){
        this.id = id;
        this.member = member;
        this.postLiked = postLiked;
    }
}
  • postLike 엔티트를 생성합니다.
  • 복합키 composite key를 사용했기 때문에 @EmbeddeId, @MapsId 어노테이션을 사용합니다.

 

Respository

@Component
public interface PostLikeRepository {
    PostLike save(PostLike postLike);
    @Transactional
    void deleteById(PostLikeCompositeKey postLikeCompositeKey);
    Optional<PostLike> findById(PostLikeCompositeKey postLikeCompositeKey);
}
  • delete 쿼리를 사용하기 때문에 @Transactional를 추가해줍니다. 안하면 에러 뜹니다....(저도 알고싶지 않...)
  • Optional로 findById 메소드를 구현한 것은 찾는 값이 null 일 때 에러를 방지하기 위해서 입니다.

 


좋아요 기능 구현을 위해 복합키를 처음 사용해봤는데 생각보다 어렵지는 않고 단순했습니다. 그냥 안써도 될 것 같다는 느낌이 드는데 공부가 좀 더 필요한 것 같습니다.

 

 

 

 

 

+ Recent posts