Java Pagination List Caching Strategies

This article explains three progressively finer-grained approaches to caching paginated lists in Java—directly caching whole pages, caching individual objects after retrieving their IDs, and caching both ID lists and object entries using Redis structures—along with code examples and performance considerations.

Code Ape Tech Column
Code Ape Tech Column
Code Ape Tech Column
Java Pagination List Caching Strategies

1. Directly Cache Paginated List Results

This is the simplest solution: after querying a page of data, cache the entire page result using a key that combines page number, size, and query parameters.

Pseudo‑code:

public List<Product> getPageList(String param, int page, int size) {
  String key = "productList:page:" + page + "size:" + size + "param:" + param;
  List<Product> dataList = cacheUtils.get(key);
  if (dataList != null) {
    return dataList;
  }
  dataList = queryFromDataBase(param, page, size);
  if (dataList != null) {
    cacheUtils.set(key, dataList, Constants.ExpireTime);
  }
}

The advantage is simplicity and speed, but the granularity is large; any data change requires updating or invalidating the whole page cache, which may involve costly keys commands in Redis.

2. Query Object ID List, Then Cache Each Object Entry

To achieve finer granularity, first retrieve only the IDs of the objects for the requested page, then cache each object individually.

Core steps:

Query the paginated ID list from the database.

// From database query paginated product ID list
List<Long> productIdList = queryProductIdListFromDabaBase(param, page, size);

Corresponding SQL:

SELECT id FROM products ORDER BY id ASC LIMIT (page-1)*size, size;

Batch‑get cached objects.

Map<Long, Product> cachedProductMap = cacheUtils.mget(productIdList);

Identify IDs that missed the cache.

List<Long> noHitIdList = new ArrayList<>(cachedProductMap.size());
for (Long productId : productIdList) {
  if (!cachedProductMap.containsKey(productId)) {
    noHitIdList.add(productId);
  }
}

Batch‑query missing objects from the database and load them into the cache.

List<Product> noHitProductList = batchQuery(noHitIdList);
Map<Long, Product> noHitProductMap = noHitProductList.stream()
    .collect(Collectors.toMap(Product::getId, Function.identity()));
cacheUtils.mset(noHitProductMap);
cachedProductMap.putAll(noHitProductMap);

Assemble the final ordered list.

for (Long productId : productIdList) {
  Product product = cachedProductMap.get(productId);
  if (product != null) {
    result.add(product);
  }
}

This method keeps cache granularity small and uses batch operations to maintain good performance.

3. Cache Object ID List and Each Object Entry Simultaneously

When dealing with high‑traffic feeds (e.g., social‑media timelines), store the ID list in a Redis ZSet where the member is the object ID and the score is the creation timestamp.

Using ZREVRANGE with pagination parameters retrieves the ordered ID list. After obtaining the IDs, batch‑fetch the full objects from cache (or database) and assemble the page.

For simple object structures, mget / hmget suffice; for complex structures, Redis pipelines or Lua scripts can improve throughput.

4. Summary

The article presents three caching strategies for paginated lists:

Directly cache the whole page result.

Cache each object after retrieving a paginated ID list.

Cache both the ID list (using Redis ZSet) and each object entry.

All three approaches emphasize fine‑grained cache control and batch loading to achieve high performance while maintaining data consistency.

Final Note

If you found this tutorial helpful, please like, view, share, and bookmark the article; your support encourages the author to continue producing quality content.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaperformancepagination
Code Ape Tech Column
Written by

Code Ape Tech Column

Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.