Spring Cache

Spring Cache 缓存地址

1、简介

Spring 从 3.1 开始定义了 org.springframework.cache.Cache 和
org.springframework.cache.CacheManager 接口来统一不同的缓存技术; 并支持使用
JCache(JSR-107)注解简化我们开发;

 Cache 接口为缓存的组件规范定义,包含缓存的各种操作集合; Cache 接 口 下 Spring 提 供 了 各 种 xxxCache 的 实 现 ; 如 RedisCache , EhCacheCache , ConcurrentMapCache 等;

每次调用需要缓存功能的方法时,Spring 会检查检查指定参数的指定的目标方法是否已
经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓 存结果后返回给用户。下次调用直接从缓存中获取。

 使用 Spring 缓存抽象时我们需要关注以下两点;
 1、确定方法需要被缓存以及他们的缓存策略
 2、从缓存中读取之前缓存存储的数据

2、基础概念

在这里插入图片描述

3、注解

在这里插入图片描述
@Cacheable:触发数据保存到​​缓存。

@CacheEvict:触发​​删除缓存逐出。

@CachePut:在不影响方法执行的更新缓存。

@Caching:组合以上多个缓存操作。

@CacheConfig:在类级别 共享缓存相关配置。

4、表达式语法

在这里插入图片描述

5、缓存穿透问题解决

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

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

允许 null 值缓存

6.缓存使用

6.1 @Cacheable注解的使用

在这里插入图片描述

 //1.获取一级分类,
//每一个需要缓存的数据,都指定放到指定名称的缓存[缓存分区(按业务类型)]
@Cacheable({"category"})
 //@Cacheable,开启缓存。代表此方法的结果需要缓存。
	//若缓存有,方法不调用,否则调用方法,将方法结果放入缓存
@Override
public List<CategoryEntity> getLevelOneCategorys() {
    System.out.println("getLevelOneCategorys...获取一级分类数据");
    QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<CategoryEntity>().eq("parent_cid", 0);
    List<CategoryEntity> entities = baseMapper.selectList(wrapper);
    return entities;
}

1). @Cacheable注解的细节

    1.每一个需要缓存的数据,都指定放到指定那个名称的缓存[缓存分区(按业务类型)]
    2. @Cacheable({"category"}),//开启缓存。
            代表此方法的结果需要缓存。若缓存中有,方法不调用;否则调用方法,最后将方法结果放入缓存
    3. 默认行为
       	1).若缓存中有,方法不调用
        2).key默认自带生成:缓存的名称::SimpleKey[],(自动生成key值)
        3).缓存的value值,默认使用jdk序列化机制,将序列化的数据存入redis
        4).默认过期时间(ttl):-1 ,代表永不过期
自定义缓存配置

spel 详细介绍:

      自定义设置
		1).指定生成缓存生成的key。key属性指定,接受一个spel,spel 详细介绍
		2).指定缓存数据存活时间。 
			配置文件修改ttl:spring.cache.redis.time-to-live=3600000
		3).将数据保存为json格式
1.a).设置缓存key、value(缓存名称)

在这里插入图片描述

1.b).设置过期时间 、数据转为json格式(为了缓存数据为json)
配置文件缓存配置(application.properties)
#配置redis
spring.redis.host=192.168.56.10
spring.redis.port=6379

#配置Spring Cache
spring.cache.type=redis
#spring.cache.cache-names=qq

#设置过期时间为1小时,单位:毫秒 ***
spring.cache.redis.time-to-live=3600000
#指定缓存名字前缀就用,不指定就用缓存名称作为前缀
spring.cache.redis.key-prefix=CACHE_
spring.cache.redis.use-key-prefix=true
#是否缓存空值null,防止缓存穿透
spring.cache.redis.cache-null-values=true
缓存配置类
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
public class MyCacheConfig {
    @Bean
    RedisCacheConfiguration cacheConfiguration(CacheProperties cacheProperties) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //设置缓存key
        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) {
        //设置ttl(过期时间)
            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;
    }
问题:配置文件的配置没有生效,介绍如下,代码如上(缓存配置类)

/**
* 配置文件的东西没有用上:如ttl(过期时间)
* 1.原来和配置文件绑定的配置类是:
* @ConfigurationProperties(prefix = “spring.cache”)
* public class CacheProperties
* 2.要让他生效,@EnableConfigurationProperties(CacheProperties.class)
* 法1:注入
* @Autowired CacheProperties cacheProperties
* 法2:方法参数 ***
* RedisCacheConfiguration cacheConfiguration(CacheProperties cacheProperties){
*/

测试:http://localhost:10000/#

在这里插入图片描述

2).缓存删除 @CacheEvict

逻辑:修改数据、删除缓存----失效模式

@CacheEvict:失效模式(修改数据,删除缓存,下一次查询数据库,把数据添加到缓存)
指定缓存名称value、key
@CacheEvict(value = {“category”},key = “getLevelOneCategorys”)

代码
//级联更新所有关联数据
 @Override
    @CacheEvict(value = {"category"},key = "'getLevelOneCategorys'")
    public void updateDetail(CategoryEntity category) {
        //更新分类表
        this.updateById(category);
        //保证冗余字段数据一致
        if (!StringUtils.isEmpty(category.getName())) {
            //同步更新其他关联表的数据
            categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
            // TODO  更新其他表关联
        }
    }
问题:

“message”: “EL1008E: Property or field ‘selectIndexList’ cannot be found on object of type ‘org.springframework.cache.interceptor.CacheExpressionRootObject’ - maybe not public or not valid?”
解决:
在这里插入图片描述

测试

修改分类数据,缓存会删除

删除category指定缓存
@CacheEvict(value = {“category”},key = “getLevelOneCategorys”) ,
删除category下的所有缓存删除
@CacheEvict(value = {“category”},allEntries = true)

3).多个组合注解 @Caching

修改获得json数据
在这里插入图片描述

evict表示清除缓存

在这里插入图片描述

@Caching 同时进行多个缓存操作
删除多个指定名称下指定缓存
@Caching(evict = {
@CacheEvict(value = {“category”}, key = “‘getLevelOneCategorys’”),
@CacheEvict(value = {“category”}, key = “‘getCatalogJson’”)
})

测试
3.1).gulimall.com
3.2). 修改分类数据,缓存会删除

4). @CachePut 双写模式

注解说明

1.@CacheEvict:失效模式(修改数据,删除缓存,下一次查询数据库,把数据添加到缓存)
指定缓存分区名value、key
@CacheEvict(value = {“category”},key = “getLevelOneCategorys”) , 删除category指定缓存
2.@CacheEvict(value = {“category”},allEntries = true) ,删除category下的所有缓存
3. @Caching 同时进行多个缓存操作
4.存储统一类型的数据,放在指定统一分区,方便删除库存(allEntries = true)
@CachePut//双写模式

7.springcache 的原理与不足

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值