SpringBoot数据缓存(@Cacheable)

  • 2018-04-09
  • 45
  • 0
  • 0

缓存可以缓解数据库访问的压力,Spring自身不提供缓存的存储实现,需要借助第三方,比如JCache、EhCache、Hazelcast、Redis、Guava等,目前公司采用的是redis。Spring Boot可以自动化配置合适的缓存管理器(CacheManager),默认采用的是ConcurrentMapCacheManager(java.util.concurrent.ConcurrentHashMap)。


(1)添加 spring-boot-starter-cache 依赖
Xml代码

    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-cache</artifactId>  
    </dependency>  

(2)开启缓存功能(使用redis存储)
Java代码

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    /**
     * 自定义key. 这个可以不用
     * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append("<");
                sb.append(method.getName());
                sb.append(">");
                sb.append("{");
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                sb.append("}");
                return sb.toString();
            }
        };

    }

    @Bean
    public CacheManager cacheManager(
            @SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        //设置redis缓存key的默认过期时间(单位:秒)
        //一天 = 86400秒
        redisCacheManager.setDefaultExpiration(86400);
        return redisCacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(
            RedisConnectionFactory factory) {

        StringRedisTemplate template = new StringRedisTemplate(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);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }
}

(3)缓存数据
对于缓存的操作,主要有:@Cacheable、@CachePut、@CacheEvict。
@Cacheable
Spring 在执行 @Cacheable 标注的方法前先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,执行该方法并将方法返回值放进缓存。
参数: value缓存名、 key缓存键值、 condition满足缓存条件、unless否决缓存条件
Java代码

        @Cacheable(cacheNames = "demand2brandTime",  unless = "#result == null" , keyGenerator = "keyGenerator")
    public User findById(final Long id) {  
        System.out.println("cache miss, invoke find by id, id:" + id);  
        for (User user : users) {  
            if (user.getId().equals(id)) {  
                return user;  
            }  
        }  
        return null;  
    }  

@CachePut
和 @Cacheable 类似,但会把方法的返回值放入缓存中, 主要用于数据新增和修改方法。
Java代码

    @CachePut(value = "user", key = "#user.id")  
    public User save(User user) {  
        users.add(user);  
        return user;  
    }  

@CacheEvict
方法执行成功后会从缓存中移除相应数据。
参数: value缓存名、 key缓存键值、 condition满足缓存条件、 unless否决缓存条件、 allEntries是否移除所有数据(设置为true时会移除所有缓存)
Java代码

    @CacheEvict(value = "user", key = "#user.id") // 移除指定key的数据  
    public User delete(User user) {  
        users.remove(user);  
        return user;  
    }  

Java代码

     @CacheEvict(value = "demand2brandTime" , allEntries = true )
    @RequestMapping(value="deleteCacheable" , method = RequestMethod.POST)
    @LogInfo(message = "删除redis-demand2brandTime缓存" , model = "deleteCacheable" , logType = LogInfo.TYPE_INFO)
    public Result deleteCacheable(){
        return Result.builder().success(true).build();
    }

SpringBoot可以自动配置不需要什么特殊设置即可使用。

调用接口,查看redis是否缓存成功。

以上,谢谢!

评论

还没有任何评论,你来说两句吧

发表评论