You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何缓存Pageable?分页对象的缓存处理

Spring Boot中针对Pageable分页数据的缓存处理方法

要实现分页数据的缓存,核心是让缓存Key能唯一标识每一页的请求参数——毕竟不同的页码、每页大小、排序规则对应不同的数据集。下面是具体的实现方案:

1. 配置@Cacheable的唯一Key

直接使用Pageable对象里的核心参数(页码、每页大小、排序规则)生成缓存Key,确保不同分页请求对应不同的缓存条目。

方式一:参数拼接生成Key

@Service
public class MarketServiceImpl implements MarketService {

    @Autowired
    MarketDao marketDao;

    @Cacheable(value = "marketData", key = "#pageable.pageNumber + '_' + #pageable.pageSize + '_' + #pageable.sort.toString().replace(' ', '')")
    public Page<StockMarkets> findAllMarket(Pageable pageable){
        return marketDao.findAll(pageable);
    }
}

这里对sort.toString()做了空格替换,避免Key中出现特殊字符导致缓存异常。

方式二:用SimpleKey生成安全Key

如果担心字符串拼接的格式问题,可以用Spring内置的SimpleKey自动处理参数哈希,生成稳定的Key:

@Cacheable(value = "marketData", key = "T(org.springframework.cache.interceptor.SimpleKey).of(#pageable.pageNumber, #pageable.pageSize, #pageable.sort)")

2. 处理Sort对象的序列化问题

Sort对象默认序列化可能存在格式不稳定的情况,比如不同环境下toString()输出有差异。如果用Redis作为缓存,建议配置Jackson序列化器统一处理Sort和Page对象:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        
        template.setValueSerializer(serializer);
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}

3. 缓存更新与清除

当StockMarkets数据发生新增、修改或删除时,需要清除对应缓存避免脏数据:

@CacheEvict(value = "marketData", allEntries = true)
public void updateMarket(StockMarkets market) {
    marketDao.save(market);
}

如果只想清除特定分页的缓存,可以在@CacheEvict的key参数中指定对应分页的参数。

内容的提问来源于stack exchange,提问作者Pratyush Pranjal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:27:54