Spring/[P] 도서 대여 프로그램

🩷 좋아요 기능 (추가, 취소) 🩷

alsruds 2023. 12. 16. 23:05
  • Controller → Service → Repository

 

💟 Controller

☑️ 좋아요 추가 : 좋아요를 누르는 회원 ID & 책 ID 를 담은 데이터 (addLikesCount) 를 기반으로 좋아요를 반영한다

☑️ 좋아요 취소 : 삭제하려는 Likes 테이블의 id 값을 입력받는다

@RestController
@RequestMapping("/book/likes")
@RequiredArgsConstructor
public class LikesController {
    private final LikesService likesService;

    // 좋아요 추가
    @PostMapping()
    public ResponseEntity<String> addLikes(@RequestBody AddLikesCount addLikesCount) {
        HttpStatus response = likesService.addLikes(addLikesCount);

        if (response == HttpStatus.CONFLICT) {
            return new ResponseEntity<>("이미 좋아요를 눌렀습니다", HttpStatus.CONFLICT);
        } else {
            return new ResponseEntity<>("좋아요가 반영되었습니다", HttpStatus.OK);
        }
    }

    // 좋아요 취소
    @DeleteMapping("/{id}")
    public void deleteLikes(@PathVariable("id") Long id) {
        likesService.deleteLikes(id);
    }
}

 

💟 Service

☑️ 좋아요 추가 : Likes 테이블에 새로운 레코드를 추가한 후, 해당 book id 를 가진 likesCount 를 +1 한다

☑️ 좋아요 취소 : 해당 Likes 테이블의 id 를 가진 레코드를 삭제한 후, 해당 book id 를 가진 likesCount 를 -1 한다

@Service
@Transactional
@RequiredArgsConstructor
public class LikesService {
    private final LikesRepository likesRepository;
    private final MemberRepository memberRepository;
    private final BookRepository bookRepository;

    // 좋아요 추가
    public HttpStatus addLikes(AddLikesCount addLikesCount) {
        Member member = memberRepository.findById(addLikesCount.getMemberId()).orElseThrow(RuntimeException::new);
        Book book = bookRepository.findById(addLikesCount.getBookId()).orElseThrow(RuntimeException::new);

        // 1. 테이블에 새로운 레코드 추가
        if (likesRepository.existsByMemberAndBook(member, book)) {
            // 이미 존재하는 레코드인 경우 추가 X 오류 코드 반환
            return HttpStatus.CONFLICT;
        } else {
            likesRepository.save(new Likes(member, book));

            // 2. book entity 의 likesCount +1
            book.addLikesCount();
            return HttpStatus.OK;
        }
    }

    // 좋아요 취소
    public void deleteLikes(Long id) {
        Likes likes = likesRepository.findById(id).orElseThrow(RuntimeException::new);
        Book book = bookRepository.findById(likes.getBook().getId()).orElseThrow(RuntimeException::new);

        // 1. 해당 Likes 테이블의 id 가진 레코드 삭제
        likesRepository.deleteById(id);

        // 2. book entity 의 likesCount -1
        book.deleteLikesCount();
    }
}

 

💟 Repository

☑️ service 에서 findById, deleteById 메서드를 호출하기 위해 JpaRepository 인터페이스를 상속받는다

☑️ 이미 좋아요를 누른 상태인지 판별하기 위한 메서드를 등록한다 (existsByMemberAndBook)

@Repository
public interface LikesRepository extends JpaRepository<Likes, Long> {
    boolean existsByMemberAndBook(Member member, Book book);
}

 

💟 Dto

☑️ 좋아요를 누르는 사용자와 해당 책의 ID 값을 담아 Controller 로 전달한다

@Getter
@NoArgsConstructor
public class AddLikesCount {
    private Long memberId;
    private Long bookId;
}

 

 

💡TEST💡

 

< 좋아요 추가 >

· Postman

 

· DataGrip

Likes 테이블에 레코드 추가
해당 책에 likeCount +1

 

< 좋아요 취소 >

· Postman

 

· DataGrip

Likes 테이블에서 삭제
해당 책의 likeCount -1