나와바리 - 좋아요 기능

Sungmin·2023년 4월 24일
0

좋아요 엔티티

public class Heart {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "heart_id")
    private Long id;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "review_id")
    private Review review;

    private boolean liked;

    //== 생성 메서드 ==//
    public static Heart createHeart(Member member, Review review, Boolean liked) {
        Heart heart = new Heart();
        heart.setMember(member);
        heart.setReview(review);
        heart.setLiked(false);
        return heart;
    }

    public void like() {
        if (!this.liked){
            this.liked = true;
            this.review.addHeart(this);
        } else {
            this.unlike();
        }
    }

    public void unlike() {
        if (this.liked) {
            this.liked = false;
            this.review.removeHeart(this);
        }
    }


    @Builder
    public Heart(Member member, Review review, boolean liked) {
        this.member = member;
        this.review = review;
        this.liked = liked;
    }

회원과 리뷰엔티티에 다 대 일 관계를 맺고, 생성 메서드와 좋아요로직을 만들어 두었다.


레포지토리

public class HeartRepository {

    @PersistenceContext
    private final EntityManager em;


    public void save(Heart heart) {
        em.persist(heart);
    }

    public Heart findOne(Long id) {
        return em.find(Heart.class, id);
    }

    public Heart findLiked(Member member, Review review) {
            return em.createQuery("select h from Heart h where h.member = :member and h.review = :review", Heart.class)
                    .setParameter("member", member)
                    .setParameter("review", review)
                    .getResultList()
                    .stream()
                    .findFirst()
                    .orElse(null);

        }

    public void delete(Heart heart) {
        em.remove(heart);
    }

save와 findOne, findLiked, delete를 만들어 줌
findLiked는 리뷰정보와 회원정보를 받아 이미 DB에 값이 있을 경우 반환 해 주고 없을 경우 null을 반환하게 만들어 주었다.


서비스

    public int toggleHeart(Long memberId, Long reviewId) {
        //회원과 리뷰를 DB에서 찾아서 Heart객체가 존재하는지 체크(존재한다 == true)
        Member member = memberRepository.findOne(memberId);
        Review review = reviewRepository.findOne(reviewId);
        Heart heart = heartRepository.findLiked(member, review);

        if (heart == null) {
            heart = Heart.createHeart(member, review, false);
            heart.like();
        }
        else {
            heart.unlike();
            heartRepository.delete(heart);
        }
        heartRepository.save(heart);
        return review.getLikeCount();
    }

이미 좋아요를 누른 회원인지 처음 누르 회원인지 판별하기 위해 좋아요를 처음 누르면 Heart객체를 생성하였고, 회원아이디와 리뷰아이디를 받아와 findLiked해 주었을 때 값이 없을 경우 createHeart로 객체를 생성하여 넣어주고 like메서드 실행. true로 있을 경우 unlike 메서드 실행 후 삭제. 값을 save로 반영하여 반환.


테스트

    @Test
    public void 좋아요기능() throws Exception {
        //given
        Member member = Member.builder()
                .profile_nickname("Kim")
                .build();
        em.persist(member);

        Review review = Review.builder()
                .likeCount(2)
                .title("맛있음")
                .build();
        em.persist(review);


        Heart heart = Heart.builder()
                .member(member)
                .review(review)
                .liked(true)
                .build();
        em.persist(heart);

        //when
        int heartCount = heartService.toggleHeart(member.getId(), review.getId());

        //Then
        assertThat(heartCount).isEqualTo(1);
    }

테스트코드는 아직 미숙한 점이 많은 것 같다. 좋아요의 개수가 2개인 리뷰에 이미 좋아요를 누른 회원이 다시 누를 경우를 생각하여 테스트 코드를 작성하였다.
예상값은 1이고 결과도 1이 나왔다.

profile
Let's Coding

0개의 댓글