SpringBoot 整合 Redis 实现声明式缓存
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)添加配置文件
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-wait=100ms
spring.redis.jedis.pool.max-idle=100
spring.redis.jedis.pool.min-idle=10
3)配置类
配置 RedisTemplate
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
// 配置序列化器
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key 采用 String 的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash 的 key 也采用 String 的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value 序列化方式采用 jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash 的 value 序列化方式采用 jackson 序列化器
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
4)使用 RestTemplate
常用方法:
ValueOperations opsForValue() 获得 string 类型的操作对象
HashOperations opsForHash 获得 hash 类型的操作对象
…
ValueOperations 操作对象
set(key,value) 保存 key-value
Object get(key) 读取 value
使用缓存的步骤:
先查询缓存
如果查到直接返回
如果查不到,查询数据库
数据库查到,保存缓存中
数据库查不到返回 null
@Override
public Goods findById(Long id) {
ValueOperations<String, Object> ops = template.opsForValue();
//先查缓存,缓存有,直接返回不执行同步块,提高效率
Goods goods = (Goods ) ops.get("goods-"+id);
if(goods == null) {
//上锁,保证查询缓存,查询数据库,保存缓存同步执行
synchronized (this) {
//先查询缓存
goods = (Goods ) ops.get("goods-" + id);
//如果查到直接返回
if (goods!= null) {
System.out.println("从缓存查到" + goods);
return goods;
} else {
//如果查不到,查询数据库
System.out.println("缓存没有,查询数据库");
goods = goodsMapper.selectById(id);
if (goods!= null) {
//数据库查到,保存缓存中
System.out.println("数据库查到" + goods);
ops.set("goods-" + id, goods);
return goods;
}
}
System.out.println("数据库没有查到");
return null;
}
}
return goods;
}
===================================================================
编程式缓存使用复杂,代码侵入性高,推荐使用声明式缓存,通过注解来实现热点数据缓存。
1)在启动类上添加注解
//启动缓存
@EnableCaching
2)Redis 的配置类
@Configuration
public class RedisConfig {
@Bean
public RedisCacheConfiguration provideRedisCacheConfiguration(){
//加载默认配置
RedisCacheConfiguration conf = RedisCacheConfiguration.defaultCacheConfig();
//返回 Jackson 序列化器
return conf.serializeValuesWith(
RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}
}
3)缓存相关注解
@CacheConfig 使用在 Service 类上,可以配置缓存名称,如:
@CacheConfig(cacheNames = “books”)
@Cacheable 使用在查询方法上,让方法优先查询缓存
@CachePut 使用在更新和添加方法上,数据库更新和插入数据后同时保存到缓存里
@CacheEvict 使用在删除方法上,数据库删除后同时删除缓存
注意:缓存的实体类必须实现序列化接口
案例:Reids 缓存品牌
//配置缓存名称为 brand
@CacheConfig(cacheNames = "brand")
评论