SpringCache
1、什么是SpringCache
Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现。
- EHCache
- Caffeine
- Redis
我们不需要主动显式要求使用什么缓存实现。
比如我们要使用redis实现,只需要在项目中导入 redis的 Java客户端的依赖比如: SpringDataRedis。springcache会自动使用。
2、准备工作
在这里,将**_redis_**
作为**_SpringCache_**
的缓存实现。
2.1、添加redis起步依赖
<!-- redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 连接池依赖 -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version>
</dependency>
2.2、配置文件配置数据源
根据SpringBoot的版本不同,配置略有不同。
如果是SpringBoot 3.x
spring:
data:
redis:
host: localhost
port: 6379
password: 123456
lettuce:
pool:
max-active: 8 # 最大连接数
max-idle: 8 #最大空闲数
min-idle: 0 # 最小空闲数
max-wait: 100 # 最大等待时间
如果是SpringBoot 2.x
spring:
redis:
host: 101.43.108.196
port: 6379
password: 123456
lettuce:
pool:
max-active: 8 # 最大连接数
max-idle: 8 #最大空闲数
min-idle: 0 # 最小空闲数
max-wait: 100 # 最大等待时间
补充:
关于客户端的选择:
建议使用[Lettuce](https://lettuce.io/)
,而这也是Spring Data Redis默认使用的。因为它是基于 Netty 开发,支持非阻塞式 IO,性能会更好。
2.3、配置类,配置redisTemplate对象,主要是设置 序列化器
@Configuration
@Slf4j
public class RedisTemplateConfiguration {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate redisTemplate=new RedisTemplate();
//设置key的序列化器,默认为JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
补充:redisTemplate的使用()
@Autowired
private RedisTemplate redisTemplate;
Object name = redisTemplate.opsForValue().get("NAME");
2.4、添加Spring Cache的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
3、常用注解
@EnableCaching
加在SpringBoot项目的启动类上。
@CachePut
@CachePut(cacheNames = "usercache", key = "#user.id")
cacheNames :用于作为缓存的键的生成规则的一部分。
key :也是作为键值对生成的规则,可以写死,也可以动态生成!!!
比如:@CachePut(cacheNames = "usercache", key = "1")
在缓存中生成的key就是,usercache::1
但是,这样时写死的,key后面应该是动态绑定的。基本上有5种写法。
@CachePut(cacheNames = "usercache", key = "#user.id") //名为user的参数
@CachePut(cacheNames = "usercache", key = "#result.id") //#result是方法返回值
@CachePut(cacheNames = "usercache", key = "#p0.id") //p0是第一个参数
@CachePut(cacheNames = "usercache", key = "#a0.id") //a0也是第一个参数
@CachePut(cacheNames = "usercache", key = "#root.args[0].id") //也是第一个参数
public User insert(@RequestBody User user){
springCacheUserMapper.insert(user);
return user;
}
@Cacheable
1、如果不需要动态生成 键值对 中的键,那么使用@Cacheable(value = "xxx")
比如: @Cacheable(value = "username")
这里的"username" 会作为redis数据库中的 key
2、如果需要使用 动态生成 键值对 中的键,则需要像下面一样使用。
@Cacheable(cacheNames = "usercache", key = "#id")
动态生成的键值对的键 usercache::#{id}。先去缓存中查这个key存不存在,不存在才会进行对应的方法体。并且在方法体执行完之后,将方法返回的数据存入缓存中。
@CacheEvict
@CacheEvict(cacheNames = "usercache",key = "#id") //删除某个键值对
@CacheEvict(cacheNames = "usercache",allEntries = true) //表示删除usercache::下的所有的键值对
4、实践
4.1、根据地址簿id查询,一条地址记录
在这个controller方法上添加注解,先查询缓存再查询数据库,并且支持存入数据库
/**
* @ description 根据id查询地址信息
* @param id
* @ return com.zyp.pojo.Result
* @ author DELL
*/
@GetMapping("/one")
@Cacheable(cacheNames = "useraddress", key = "#id")
public Result<AddressVo> selectById(Long id){
AddressVo res = addressService.selectById(id);
return Result.success(res);
}
假如id=1,生成的redis中的key 是 useraddress::1
4.2、当发生增、删、改,把缓存的数据删除
/**
* @ description 删除地址
* @ param address
* @ return com.zyp.pojo.Result
* @ author DELL
*/
@PostMapping("/del")
@CacheEvict(cacheNames = "useraddress", allEntries = true)
public Result delete(@RequestBody Address address){
Long id = address.getId();
addressService.delete(id);
return Result.success();
}
这里举删除的例子,会把useraddress::
下的所有的键值对删除。