Spring Boot 的 Redis 最佳实践
1. pom.xml引用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. RedisConfig 配置
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// 设置缓存过期时间 (秒)
cacheManager.setDefaultExpiration(2 * 60);
return cacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
setJsonSerializer(template);//设置序列化工具
template.afterPropertiesSet();
return template;
}
// json 序列化定义
private void setJsonSerializer(StringRedisTemplate template) {
// 定义 key 的序列化方式为 string
// Long类型会出现异常信息;需要我们上面的自定义key生成策略,一般没必要
// 需要注意这里Key使用了 StringRedisSerializer,那么Key只能是String类型的,不能为Long,Integer,否则会报错抛异常。
// 就是假如 PostRepository 里定义的 @Cacheable(key="#p0") 的话就会报错,因为这样作为key的是int型,key必须为String。
StringRedisSerializer redisSerializer = new StringRedisSerializer();
// JdkSerializationRedisSerializer redisSerializer = new JdkSerializationRedisSerializer();
template.setKeySerializer(redisSerializer);
template.setHashKeySerializer(redisSerializer);
// 定义 value 的序列化方式为 json
@SuppressWarnings({
"rawtypes", "unchecked"})
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);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
}
}
3. Service层使用
@Service
@CacheConfig(cacheNames="cityCache") // 本类内方法指定使用缓存时,默认的名称就是 cityCache
@Transactional
public class CityServiceImpl extends AbstractService<City> implements CityService {
private Logger log = LoggerFactory.getLogger(CityServiceImpl.class);
@Autowired
private CityMapper cityMapper;
// 因为必须要有返回值,才能保存到数据库中,如果保存的对象的某些字段是需要数据库生成的,
// 那保存对象进数据库的时候,就没必要放到缓存了
// 必须要有返回值,否则没数据放到缓存中
@CachePut(key="'cityId:' + #p0.id") //#p0表示第一个参数
public City insert(City city){
cityMapper.insert(city);
//u对象中可能只有只几个有效字段,其他字段值靠数据库生成,比如id
return cityMapper.selectByPrimaryKey(city.getId());
}
@CachePut(key="'cityId:' + #p0.id")
public City updateCity(City city){
cityMapper.updateByPrimaryKeySelective(city);
//可能只是更新某几个字段而已,所以查次数据库把数据全部拿出来全部
return cityMapper.selectByPrimaryKey(city.getId());
}
// @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
@Cacheable(key="'cityId:' + #p0")
public City find(Integer id){
log.info("根据id=" + id +"获取用户对象,从数据库中获取");
return cityMapper.selectByPrimaryKey(id);
}
public List<City> findAll() {
return cityMapper.selectAll();
}
// 删除缓存名称为 userCache ,key等于指定的id对应的缓存
@CacheEvict(key="'cityId:' + #p0")
public void delete(Integer id){
cityMapper.deleteByPrimaryKey(id);
}
// 清空缓存名称为 userCache(看类名上的注解)下的所有缓存
//如果数据失败了,缓存时不会清除的
@CacheEvict(allEntries = true)
public void deleteAll(){
// cityMapper.deleteByPrimaryKey();
}
}
还没有评论,来说两句吧...