ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA, Redis]페이지별 결과 캐싱
    Spring Framework 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 = 0
    page = 1

     

    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"

     

    반응형

    댓글

Designed by Tistory.