java 배우기/TIL

팀프로젝트 like 기능 구현하기

checkuu 2024. 9. 5. 20:40

게시글과 댓글에 좋아요 기능 구현하기

 

Entity

@Entity
@Getter
@NoArgsConstructor
public class Likes extends BaseEntity {

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id" , nullable = false)
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "comment_id")
    private Comment comment;

    public Likes(User user, Post post){
        this.user = user;
        this.post = post;
    }

    public Likes(User user, Comment comment){
        this.user = user;
        this.comment = comment;
    }
}

사용자와 게시글 댓글을 연결해주기

 

Service

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class LikeService {

    private final LikesRepository likesRepository;
    private final UserRepository userRepository;
    private final PostRepository postRepository;
    private final CommentRepository commentRepository;

    @Transactional
    public void likePost(Long postId, AuthUser authUser) {
        User user = userRepository.findById(authUser.getUserId()).orElseThrow(() -> new EntityNotFoundException("해당 유저가 존재 하지 않습니다."));
        Post post = postRepository.findById(postId).orElseThrow(() -> new EntityNotFoundException("해당 게시글이 존재하지 않습니다."));

        //게시글의 유저가 있는지 확인 해당게시글의 유저id와 좋아요 하려는 유저가 같은 사람인지 확인하는 조건문
        if (post.getUser() != null && ObjectUtils.nullSafeEquals(user.getId(), post.getUser().getId())) {
            throw new EntityAlreadyExistsException("자신이 작성한 게시글에는 좋아요를 누를 수 없습니다.");
        }//같은사람이 아니라면 like를 저장 진행

        if (likesRepository.findByUserAndPost(user, post).isPresent()) {
            throw new EntityAlreadyExistsException("이미 좋아요한 게시글 입니다.");
        } //이미 좋아요한 이력이 있는 게시글이면 좋아요 못하게 방지

        likesRepository.save(new Likes(user, post));
        post.increaseLikeCount();
    }

    @Transactional
    public void deleteLikePost(Long postId, AuthUser authUser) {
        //게시글이 있는지 확인
        Post post = postRepository.findById(postId).orElseThrow(() -> new EntityNotFoundException("해당 게시글이 존재하지 않습니다."));
        //유저 id 확인
        User user = userRepository.findById(authUser.getUserId()).orElseThrow(() -> new EntityNotFoundException("해당 유저가 존재 하지 않습니다."));
        //유저와 게시글 확인해서 해당 유저가 좋아요했는지 확인
        Likes like = likesRepository.findByUserAndPost(user, post).orElseThrow(() -> new EntityNotFoundException("좋아요를 하지 않았습니다."));

        likesRepository.delete(like);
        post.decreaseLikeCount();
    }

    @Transactional
    public void likeComment(Long commentId, AuthUser authUser) {
        User user = userRepository.findById(authUser.getUserId()).orElseThrow(() -> new EntityNotFoundException("해당 유저가 존재 하지 않습니다."));
        Comment comment = commentRepository.findById(commentId).orElseThrow(() -> new EntityNotFoundException("해당 댓글이 존재 하지 않습니다."));

        if (comment.getUser() != null && ObjectUtils.nullSafeEquals(user.getId(), comment.getUser().getId())) {
            throw new EntityAlreadyExistsException("자신이 작성한 댓글에는 좋아요를 누를 수 없습니다.");
        }

        if (likesRepository.findByUserAndComment(user, comment).isPresent()) {
            throw new EntityAlreadyExistsException("이미 좋아요한 댓글 입니다.");
        }

        likesRepository.save(new Likes(user, comment));
        comment.increaseLikeCount();
    }

    @Transactional
    public void deleteLikeComment(Long commentId, AuthUser authUser) {
        //댓글이 있는지 확인
        Comment comment = commentRepository.findById(commentId).orElseThrow(() -> new EntityNotFoundException("해당 댓글이 존재하지 않습니다."));
        //해당 유저 확인을 위한 user 생성
        User user = userRepository.findById(authUser.getUserId()).orElseThrow(() -> new EntityNotFoundException("해당 유저가 존재 하지 않습니다."));
        //유저와 게시글 확인해서 해당 유저가 좋아요했는지 확인
        Likes like = likesRepository.findByUserAndComment(user, comment).orElseThrow(() -> new EntityNotFoundException("좋아요를 하지 않았습니다."));

        likesRepository.delete(like);
        comment.decreaseLikeCount();
    }
}

 -. 자신이 작성한 글이나 댓글에는 좋아요 누를 수 없다.

 -. 자신이 좋아요 한 글에 다시 좋아요 누를 수 없다.

 -. 삭제시 해당 유저가 좋아요 눌렀는지 확인 후 삭제 진행한다.

Service에 해당 조건을 가진 코드 구현

 

Controller

@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class LikeController {

    private final LikeService likeService;

    @GetMapping("/posts/{postId}/likes") //게시글 좋아요 생성
    public ResponseEntity<String> upLikePost (@PathVariable Long postId, @Auth AuthUser authUser){
        likeService.likePost(postId,authUser);
        return ResponseEntity.ok().body("게시글 좋아요 요청이 완료되었습니다.");
    }

    @DeleteMapping("/posts/{postId}/likes") //게시글 좋아요 삭제
    public ResponseEntity<String> deleteLikePost(@PathVariable Long postId,@Auth AuthUser authUser){
        likeService.deleteLikePost(postId,authUser);
        return ResponseEntity.ok().body("게시글 좋아요를 취소하였습니다.");
    }

    @GetMapping("/comments/{commentId}/likes") //댓글 좋아요 생성
    public ResponseEntity<String> upLikeComment(@PathVariable Long commentId, @Auth AuthUser authUser){
        likeService.likeComment(commentId,authUser);
        return ResponseEntity.ok().body("댓글 좋아요 요청이 완료되었습니다.");
    }

    @DeleteMapping("/comments/{commentId}/likes") //댓글 좋아요 삭제
    public ResponseEntity<String> deleteLikeComment(@PathVariable Long commentId,@Auth AuthUser authUser){
        likeService.deleteLikeComment(commentId,authUser);
        return ResponseEntity.ok().body("댓글 좋아요를 취소하였습니다.");
    }
}

동작 완료시 responseEntity로 완료 문구 출구

'java 배우기 > TIL' 카테고리의 다른 글

단위테스트 : 통합테스트  (0) 2024.09.09
self Invocation  (0) 2024.09.06
Spring 게시판 조회수 증가 코드 넣기  (0) 2024.09.04
Spring 좋아요 중복 방지  (1) 2024.09.03
깃허브 브랜치 삭제 반영하기  (0) 2024.09.03