수진개발서

sns만들기 프로젝트 2일차 좋아요 기능을 구현하였다.

요구사항은 다음과 같다.

 

요구사항

- 좋아요 누르기
- '좋아요'는 한번만 누를 수 있음, 중복으로 누르는 경우는 좋아요 취소

좋아요 누르기 POST /posts/{postId}/likes
- like를 한번 누를 때 마다 row가 1개씩 추가되는 방식으로 구현
- Json 형태로 리턴
- response 형태:
{ "resultCode":"SUCCESS", "result": "좋아요를 눌렀습니다." }
{ "resultCode":"SUCCESS", "result": "좋아요를 취소하였습니다." }

 

코드

Like

- 해당 좋아요를 누른 게시물과 유저를 저장해야했기에 @ManyToOne으로 연관관계를 설정해주었다.

- 추후 좋아요를 저장할때 Entity로 만들어야해서 toEntity 메서드도 만들어주었다.

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "likes")
public class Like extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "post_id")
    private Post post;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @Column(name = "deleted_at")
    private LocalDateTime deletedAt;

    public static Like toEntity(Post post, User user) {
        return Like.builder()
                .post(post)
                .user(user)
                .build();
    }
}

LikeController

- 로그인한 사람들만 좋아요를 누를 수 있기 때문에 Authentication객체를 받아 로그인검증을 진행하였다.

- 또한 결과적으로 좋아요를 눌렀다는 message만 전달하기 때문에 Service객체에서 String객체만 받도록 하였다.

	/**
     * 좋아요 및 좋아요 취소
     */
    @PostMapping
    public Response<String> addLike(@PathVariable Long postId, Authentication authentication){
        String userName = authentication.getName();
        String message = likeService.controlLike(postId, userName);
        return Response.success(message);
    }

LikeService

- post의 유무를 확인하고 해당 포스트의 댓글을 가져왔다.

- ValidateUserPost 클래스는 user, post가 유무를 확인해주는 클래스이다. 계속 반복적인 코드가 진행되어서 따로 클래스로 분리해두었다. 해당 내용은 포스팅 후에 아래에 첨부할 예정이다.

- 좋아요 및 취소 로직은 like db에서 가져온 데이터가 있으면 데이터를 삭제, 없다면 db에 저장하는 로직이다. 

public String controlLike(Long postId, String userName) {
        //유저와 게시물의 존재 유무 확인
        ValidateUserPostDto validateUserPost = validateService.validateUserPost(userName, postId);

        //like db에 user과 post가 같은게 존재하는지 확인
        Optional<Like> like = likeRepository.findByUserAndPost(validateUserPost.getUser(), validateUserPost.getPost());

        //좋아요와 취소 로직
        if(like.isPresent()){
            likeRepository.delete(like.get());
            return "좋아요를 취소했습니다.";
        }else{
            likeRepository.save(Like.toEntity(validateUserPost.getPost(), validateUserPost.getUser()));
            return "좋아요를 눌렀습니다.";
        }
    }

 

LikeRepository

- 중복 좋아요를 막기 위해서는 db에서 해당 게시물에 해당 유저가 저장한 데이터가 없어야한다. 그래서 User와 Post가 같은지를 확인하기 위해서 쿼리가 필요했고, 해당 쿼리는 쿼리메서드로 구현하였다.

- findByUserAndPost 메서드를 통해서 User과 Post가 같은 like객체를 반환해준다.

- 쿼리 메서드란, 메서드명을 규칙에 맞게 작성을 하면, 자동으로 쿼리가 생성되는 기능이다. 해당 기능에 대해 좀 더 공부가 필요할 것 같아서 추가적인 학습 후에 포스팅하여 아래에 첨부할 예정이다!

Optional<Like> findByUserAndPost(User user, Post post);

 

참고자료

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-return-types

 

Spring Data JPA - Reference Documentation

Example 119. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

https://kim-oriental.tistory.com/34

 

[JPA] Spring Data JPA - Query Methods (쿼리 메서드)

안녕하세요, Spring Data JPA의 쿼리를 생성하는 기능 중 한 개인 메서드명을 규칙에 맞게 작성을 하면, 자동으로 쿼리가 생성되는 Query Methods (쿼리 메서드) 기능에 대해서 알아보겠습니다. 아주 복

kim-oriental.tistory.com

 

profile

수진개발서

@sujin_park0607

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!