文章介绍了Spring Cache的基本使用,包括如何配置和使用不同的缓存管理器、缓存注解和缓存策略。同时,还提供了一些实际的使用示例和最佳实践,以帮助读者更好地理解和应用Spring Cache。
org.springframework.boot
spring-boot-starter-cache
org.springframework.boot
spring-boot-starter-data-redis
作用: 将方法返回值,放入缓存。通常用于新增接口
当@CachePut(value = "userCache", key = "#user.id")时,生成的key为userCache::1006
**说明:key的写法如下
● #user.id : #user指的是方法形参的名称, id指user的id属性 , 也就是使用user的id属性作为key ;
● #result.id : #result代表方法返回值,该表达式 代表以返回对象的id属性作为key ;
● #p0.id:#p0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key
● #a0.id:#a0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key
● #root.args[0].id:#root.args[0]指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;
作用: 在方法执行前,spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
@Cacheable(cacheNames = "userCache",key="#id")
当有多条件查询时,将多个条件全拼接在key后面非常不优雅,固可以使用hashCode方法。
@Cacheable(value = "userCache",key="#userDto.hashCode()",unless = "#result.size() == 0")
public ListgetList(UserDto userDto){
Listlist = userMapper.getList("%" + userDto.getName() + "%", userDto.getAge());
return list;
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
在实体类DTO中,重写hashCode方法,这样当查询条件相同时,生成的hash码也是一样的。
这里的 unless="#result.size() == 0" 表示只有当方法返回的结果(#result)不是空集合(即其大小不等于0)的时候,才会将结果存储到缓存中。如果方法的结果是一个空集合,那么这个结果就不会被缓存。
作用: 清理指定缓存。通常用于修改删除接口
@CacheEvict(cacheNames = "userCache",key = "#id")//删除某个key对应的缓存数据
@CacheEvict(cacheNames = "userCache",allEntries = true)//删除userCache下所有的缓存数据
作用: 组装其他缓存注解
● cacheable 组装一个或多个@Cacheable注解
● put 组装一个或多个@CachePut注解
● evict 组装一个或多个@CacheEvict注解
@Caching(
cacheable = {
@Cacheable(value = "userCache",key = "#id")
},
put = {
@CachePut(value = "userCache",key = "#result.name"),
@CachePut(value = "userCache",key = "#result.age")
}
)
import java.time.Duration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public RedisCacheConfiguration cacheConfiguration() {
// 设置默认的缓存过期时间为1小时
Duration ttl = Duration.ofHours(1);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(ttl) // 设置所有缓存的TTL
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()));
}
}
设置制定Key的过期时间
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1));
// 创建一个带有特定TTL的缓存配置
Map cacheConfigs = new HashMap<>();
cacheConfigs.put("userCache",
config.entryTtl(Duration.ofSeconds(10))); // 特定缓存的TTL为30分钟
return RedisCacheManager.builder(connectionFactory)
.withInitialCacheConfigurations(cacheConfigs) // 添加特定缓存配置
.cacheDefaults(config) // 默认缓存配置
.build();
}
com.github.ben-manes.caffeine
caffeine
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
// 创建并返回一个新的 Caffeine 缓存管理器
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(caffeineCacheBuilder());
return cacheManager;
}
private Caffeine