Spring Framework
[JPA, Redis]페이지별 결과 캐싱
페페로니피자
2021. 8. 11. 17:45
반응형
1. 서론
Spring Data Redis와 JPA의 페이징을 이용해서 해당 결과를 캐싱하겠습니다.
2. JPA 페이징
2. 1. query 작성
@Query("from Post")
Optional<List<Post>> findAllPosts(Pageable pageable);
- 모든 게시물 목록을 조회합니다
- Pageable 인터페이스를 파라미터로 받습니다
2. 2. Test
@Test
public void findPosts() {
Pageable pageRequest = PageRequest.of(0, 10);
List<Post> posts = postRepository.findAllPosts(pageRequest).orElseThrow(RuntimeException::new);
posts.forEach(p -> System.out.println(p.getTitle()));
}
PageRequest.of
- (상속/구현) PageRequest.class --> AbstractPageRequest.class --> Pageable.interface
- .of(int page, int size) - 몇 번째 페이지를 보여주고, 한 페이지에 얼마나 글이 들어갈지 결정
- .of() - static 메서드
PageRequest.of(0, 10)은 0번째 페이지에 10개씩 글을 보여준다는 의미입니다. 0번째는 첫 번째입니다.
2. 3. 결과
Page에 따라 결과가 다릅니다.
3. Redis 캐싱
아래와 같이 @Cacheable 애노테이션으로 편하게 메서드 단위의 redis 캐싱할 수 있습니다.
@Cacheable(cacheNames = "", value = "", key = "")
3. 1. 문제
해당 메서드에 요청이 오는 것은 캐시에 저장해 두고, 다시 요청했을 때 같은 결과를 보여줍니다. 하지만 1페이지든, 2페이지든 첫 번째 요청을 1페이지라면 해당 결과만 캐시에 저장되고, 페이지가 바뀌어서 요청이 오더라도 같은 1페이지 결과만 보여줍니다.
즉 해당 메서드에 요청이 올 때 페이지별 다른 캐싱을 해야 합니다.
3. 2. 해결
제가 선택한 방법은 아래와 같이 페이지 별 key값을 설정했습니다.
@Cacheable(cacheNames = "findPosts", value = "findPosts", key = "#boardName + #pageNo")
- cacheNames - 캐싱할 대상이 되는 메서드 이름
- value - cacheName의 alias
- key - 저장할 캐시의 이름
- "#" - SpEL(스프링 표현 언어)를 사용하여 메서드의 타깃(인자, 클래스, 메서드)이 되는 부분을 표현
메서드에서 받는 pageNo 인자를 key값에 동적으로 추가해줍니다.
3. 3. 결과
아래와 같이 페이지별로 캐시가 저장된 것을 볼 수 있습니다.
127.0.0.1:6001> keys *
// free + 페이지 번호
1) "findPost::free2"
2) "findPost::free0"
3) "findPost::free1"
반응형