• 144802

    文章

  • 854

    评论

  • 13

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

SpringCache的使用


缓存SpringCache的使用

1.导入依赖

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

2.编写配置类

@EnableConfigurationProperties(CacheProperties.class)
@Configuration
//开启缓存功能
@EnableCaching
public class MyCacheConfig {
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        //将配置文件中的所有配置都生效
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl((redisProperties.getTimeToLive()));
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith((redisProperties.getKeyPrefix()));
        }

        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }

        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }

        return config;
    }
}

3.编写application.properties配置文件内容

#缓存类型
spring.cache.type=redis
#毫秒为单位
spring.cache.redis.time-to-live=3600000
#如果指定了前缀就用我们指定的前缀CACHE_,没有默认就用缓存的名字作为前缀
spring.cache.redis.key-prefix=CACHE_
#允许使用前缀
spring.cache.redis.use-key-prefix=true
#是否缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true

4.业务逻辑方法添加注解

注解说明

@CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置 *

@Cacheable:主要方法返回值加入缓存。同时在查询时,会先从缓存中取,若不存在才再发起对数据库的访问。

@CachePut:配置于函数上,能够根据参数定义条件进行缓存,与@Cacheable不同的是,每次会真实调用函数,所以主要用于数据新增和修改操作上。

@CacheEvict:配置于函数上,通常用在删除方法上,用来从缓存中移除对应数据

@Caching:配置于函数上,组合多个Cache注解使用。

@Cacheable用法详解

 

  • 1.value/cacheNames 属性

  • 2.key属性

  • 3.keyGenerator 属性

  • 4.cacheManager 属性

  • 5.cacheResolver 属性

  • 6.condition 属性

  • 7.unless 属性

  • 8.sync 属性

 

1.value/cacheNames 属性

       如下图所示,这两个属性代表的意义相同,根据@AliasFor注解就能看出来了。这两个属性都是用来指定缓存组件的名称,即将方法的返回结果放在哪个缓存中,属性定义为数组,可以指定多个缓存;

在这里插入图片描述

//这两种配置等价 @Cacheable(value = "user") 
//@Cacheable(cacheNames = "user") 
User getUser(Integer id); 

2.key属性

       可以通过 key 属性来指定缓存数据所使用的的 key,默认使用的是方法调用传过来的参数作为 key。最终缓存中存储的内容格式为:Entry<key,value> 形式。

  1. 如果请求没有参数:key=new SimpleKey();
  2. 如果请求有一个参数:key=参数的值
  3. 如果请求有多个参数:key=newSimpleKey(params);     (你只要知道 key不会为空就行了)  

 key值的编写,可以使用 SpEL 表达式的方式来编写;除此之外,我们同样可以使用 keyGenerator 生成器的方式来指定 key,我们只需要编写一个 keyGenerator ,将该生成器注册到 IOC 容器即可。(keyGenerator的使用,继续往下看)

@Cacheable(value = "user",key = "#root.method.name")
User getUser(Integer id);

@Cacheable(value = "user",key = "#root.methodName")
User getUser(Integer id);

@Cacheable(value = "user",key = "#id")
User getUser(Integer id);

@Cacheable(value = "user",key = "#a0")
User getUser(Integer id);

@Cacheable(value = "user",key = "#p0")
User getUser(Integer id);

3.keyGenerator 属性

       key 的生成器。如果觉得通过参数的方式来指定比较麻烦,我们可以自己指定 key 的生成器的组件 id。key/keyGenerator属性:二选一使用。我们可以通过自定义配置类方式,将 keyGenerator 注册到 IOC 容器来使用。

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.Arrays;

@Configuration
public class MyCacheConfig {

    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return new KeyGenerator(){

            @Override
            public Object generate(Object target, Method method, Object... params) {
                return method.getName()+ Arrays.asList(params).toString();
            }
        };
    }

    /**
     * 支持 lambda 表达式编写
     */
    /*@Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return ( target,  method, params)-> method.getName()+ Arrays.asList(params).toString();
    }*/
}

4.cacheManager 属性

       该属性,用来指定缓存管理器。针对不同的缓存技术,需要实现不同的 cacheManager,Spring 也为我们定义了如下的一些 cacheManger 实现()

具体使用介绍,可参考:Spring Boot 整合 Redis 实现数据缓存

5.cacheResolver 属性

       该属性,用来指定缓存管理器。使用配置同 cacheManager 类似,可自行百度。(cacheManager指定管理器/cacheResolver指定解析器 它俩也是二选一使用)

6.condition 属性

       条件判断属性,用来指定符合指定的条件下才可以缓存。也可以通过 SpEL 表达式进行设置。这个配置规则和上面表格中的配置规则是相同的。

@Cacheable(value = "user",condition = "#id>0")//传入的 id 参数值>0才进行缓存
User getUser(Integer id);

@Cacheable(value = "user",condition = "#a0>1")//传入的第一个参数的值>1的时候才进行缓存
User getUser(Integer id);

@Cacheable(value = "user",condition = "#a0>1 and #root.methodName eq 'getUser'")//传入的第一个参数的值>1 且 方法名为 getUser 的时候才进行缓存
User getUser(Integer id);

7.unless 属性

       unless属性,意为"除非"的意思。即只有 unless 指定的条件为 true 时,方法的返回值才不会被缓存。可以在获取到结果后进行判断

@Cacheable(value = "user",unless = "#result == null")//当方法返回值为 null 时,就不缓存
User getUser(Integer id);

@Cacheable(value = "user",unless = "#a0 == 1")//如果第一个参数的值是1,结果不缓存
User getUser(Integer id);

8.sync 属性

    该属性用来指定是否使用异步模式,该属性默认值为 false,默认为同步模式。步模式指定 sync = true 即可异步模式下 unless 属性不可用

整体测试

 beforeInvocation属性

    清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

@CacheEvict(value="users", beforeInvocation=true)

public void delete(Integer id) {

   System.out.println("delete user by id: " + id);

}
* 1.每一个需要缓存的数据我们都来指定要放到那个名字的缓存【缓存的分区(按照业务类型分区)】
* 2. @Cacheable({"category"})
*   代表当前方法需要缓存,如果缓存中有,方法不可调用,
*    如果缓存中没有,会调用该方法,最后将方法的返回值放进缓存
* 3.默认行为
*   1) 缓存中有,方法不调用
*   2) key默认自动生成;缓存的名字::SimpleKey [](自主生成的Key值)
 如图所示: 这里我是指定了key的值,不指定的话就是SimpleKey []
*   3) 缓存的Value值,默认使用jdk序列化机制,将序列化后的数据存储到redis
*   4) 默认ttl时间 -1
* 自定义:
*   1)指定生成的缓存使用的keykey属性指定,接受一个SpEL
*   2)指定缓存的数据存活时间:配置文件中修改ttl
*   3)将数据保存为json格式
*
*   SpringCache的不足
*   读模式:
*     缓存穿透: 查询一个null的数据。解决;cache-null-values=true
*     缓存击穿:大量的高并发请求缓存,刚好这一时间数据过期。解决:加锁 sync=true
*     缓存雪崩: 大量的key同一时间过期。解决加随机时间,加过期时间
*     spring.cache.redis.time-to-live=3600000
*    写模式:(缓存与数据库一致)
*     1.读写加锁
*     2.引入Canal,感知数据库的更新去更新数据
*     3.读多写多,直接去数据库查询
*总结:
*   常规数据:读多写少,即时性,一致性要求不高的;完全可以使用spring-cache
*       写数据只要是缓存中有过期时间就行
*   特殊数据: 特殊设计

695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


发表评论

电子邮件地址不会被公开。 必填项已用*标注

自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客