Spring

[Spring]Cache

Paragon53 2025. 5. 22. 18:25

minecraft-font

#cache 

💡 Spring 정리: Cashe

📘 개념 정리

@Cacheable 메서드 결과를 캐시에 저장, 다음엔 캐시에서 조회함
@CacheEvict 캐시 무효화, 즉 삭제. 새로 저장/삭제할 때 주로 사용
@CachePut 메서드 실행 결과로 캐시 갱신 (잘 안 쓰임)
TTL (Time To Live) RedisCacheManager 설정에서 지정, 시간이 지나면 자동 삭제
키 전략 조건이 많을 경우, "productId:min:max:page:size" 같이 구성
캐시 공간 분리 서로 다른 응답 타입이면 cache name도 분리해야 안전

 

private final CommentRepository commentRepository;
private final ProductRepository productRepository;
private final OrderRepository orderRepository;

@CacheEvict(value = "comments", key = "#productId")
@Transactional
@Override
public CommentResponseDto saveComment(Long orderId, Long productId, Long userId, CommentRequestDto dto) {

    Order order = orderRepository.findById(orderId).orElseThrow();
       if(!order.getUser().getId().equals(userId)){
       throw  new CustomRuntimeException(ExceptionCode.UNAUTHORIZED_REVIEW_ACCESS);
    }
    if(order.getOrderStatus().equals(OrderStatus.PENDING)){
       throw  new CustomRuntimeException(ExceptionCode.PAYMENT_REQUIRED);
    }
    boolean notFound = order.getProductOrderList()
       .stream()
       .noneMatch(po -> po.getProductId().equals(productId));
    if(notFound){
       throw  new CustomRuntimeException(ExceptionCode.PRODUCTORDER_NOT_FOUND);
    }
    Product findByProduct = productRepository.findById(productId).orElseThrow(()-> new CustomRuntimeException(ExceptionCode.PRODUCT_CANT_FIND));
    Comment Comment = new Comment(dto, order.getUser(),findByProduct);
    Comment saveComment = commentRepository.save(Comment);
    return new CommentResponseDto(saveComment);
}

@Cacheable(value = "comments", key = "#productId")
@Transactional(readOnly = true)
@Override
public List<CommentGetInfoDto> getCommentByRating(Long productId, int min, int max, int page, int size) {

    PageRequest pageRequest = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "creatTime"));

    Page<CommentGetInfoDto> commentResponseDtos = commentRepository.findCommentsByDynamicCondition(productId, min,  max, pageRequest);

    return  commentResponseDtos.getContent();

}

@Cacheable(value = "commentCount", key = "#productId")
@Transactional(readOnly = true)
@Override
public CommentCountDto findByCommentCount(Long productId) {
    return new CommentCountDto(commentRepository.countByProductIdAndDeletedAtIsNull(productId));
}

@CacheEvict(value = "comments", key = "#productId")
@Transactional
@Override
public CommentMessageResponseDto deleteComment(Long productId, Long userId, Long reviewId) {

    Comment getComment = commentRepository.findByIdAndDeletedAtIsNull(reviewId)
       .orElseThrow(()-> new CustomRuntimeException(ExceptionCode. COMMENT_NOT_FOUND));

    if (!getComment.getUser().getId().equals(userId)) {
       throw new CustomRuntimeException(ExceptionCode. UNAUTHORIZED_COMMENT_DELETE);
    }

    getComment.markAsDeleted(true, LocalDateTime.now());

    return new CommentMessageResponseDto("정상처리", "정상적으로 삭제 되었습니다.");
}