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();
    }

}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/jeikerxiao/article/details/80776736