xmtrock
发布于 2022-07-10 / 1,147 阅读
0

SpringCache

默认的SpringCache

需要先从启动类或者配置类启用SpringCache

@EnableCaching

默认无整合redis的情况下, 缓存是存在线程安全map中, 以ConcurrentMapCacheManager去管理的. 服务停掉, 缓存数据就丢失了.

/**
* CachePut:将方法返回值放入缓存
* value:缓存的名称,每个缓存名称下面可以有多个key
* key:缓存的key
*/
@CachePut(value = "userCache",key = "#user.id")
@PostMapping
public User save(User user){
    userService.save(user);
    return user;
}

2022-10-11_163930

/**
 * CacheEvict:清理指定缓存
 * value:缓存的名称,每个缓存名称下面可以有多个key
 * key:缓存的key
 */
// 注: 以下三种写法等价
@CacheEvict(value = "userCache", key = "#p0") // p是固定写法, 0是第1个参数. 删除全部allEntries = true
//@CacheEvict(value = "userCache",key = "#root.args[0]") // 使用方法的第1个参数
// @CacheEvict(value = "userCache", key = "#id")
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
    userService.removeById(id);
}
/**
 * Cacheable:在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
 * value:缓存的名称,每个缓存名称下面可以有多个key
 * key:缓存的key
 * condition:满足条件时才缓存数据
 * unless:满足条件则不缓存. 注意redis里condition只有root还有args, 用不了result. 但是unless可以
 */
@Cacheable(value = "userCache", key = "#id", unless = "#result == null")
@GetMapping("/{id}")
public User getById(@PathVariable Long id) {
    User user = userService.getById(id);
    return user;
}

参考官方的spel表达式编写规则
spel表达式

整合Redis的SpringCache

依赖需要有

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

配置Redis连接信息

spring:
  redis:
    host: localhost
    port: 6379
    database: 7
  cache:
    type: REDIS
    redis:
      time-to-live: 1800000 #设置缓存过期时间,可选

配置序列化和过期时间(也可以不配)

@Configuration
public class SpringCacheConfig {
    /**
     * 设置CacheManager缓存规则 [本配置主要注重redis序列化和时间]
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 注意要这样配, 不要一个个点出来
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 600秒过期时间, 会覆盖yml的世界
                .entryTtl(Duration.ofSeconds(600))
                // key的string序列化方式
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                // value的json字符串序列化方式(方便观察)
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                // 不缓存空值
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory).cacheDefaults(config).build();
    }
}

使用方式同上

更多用法

// TODO