좋아요를 복합키 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 일 때 에러를 방지하기 위해서 입니다.
좋아요 기능 구현을 위해 복합키를 처음 사용해봤는데 생각보다 어렵지는 않고 단순했습니다. 그냥 안써도 될 것 같다는 느낌이 드는데 공부가 좀 더 필요한 것 같습니다.
'TIL' 카테고리의 다른 글
TIL 한달 남은 부트캠프 회고 230115 (1) | 2023.01.16 |
---|---|
TIL 두번째 멘토링 (feat. stack trace) 230114 (0) | 2023.01.16 |
TIL 복합키 composite key 230112 (0) | 2023.01.12 |
TIL 스프링 알림 기능 구현하기 SSE Server-Sent-Event 230111 (1) | 2023.01.12 |
TIL 알람 기능 구현 SSE(Server-Sent-Events) 230110 (0) | 2023.01.10 |