使用缓存有两个前置步骤
-
在 pom.xml 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 整合redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- springboot测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
在启动类上加注解 @EnableCaching
@SpringBootApplication
@EnableCaching
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}
}
常用的注解有以下几个@Cacheable、@CachePut、@CacheEvict
添加缓存
缓存的key就是配置在注解里面的值product::123,值是你方法的返回值,如果没有返回值,值就是org.springframework.cache.support.NullValue
在需要加缓存的方法上添加注解 @Cacheable(cacheNames = "product", key = "123") ,
cacheNames 和 key 都必须填,如果不填 key ,默认的 key 是当前的方法名,更新缓存时会因为方法名不同而更新失败。
如在订单列表上加缓存
@RequestMapping(value = "/list", method = RequestMethod.GET)
@Cacheable(cacheNames = "product", key = "123")
public List<Product> list() {
List<Product> products=new ArrayList<>();
for (int i = 0; i < 3; i++) {
Product product=new Product();
product.setId(i+1);
product.setName("第"+(i+1)+"件商品");
product.setPrice((double) ((i+1)*100));
products.add(product);
}
return products;
}
可能会报错,原因是对象未序列化。让对象实现 Serializable 方法即可。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {
private Integer id;
private String name;
private Double price;
}
重启项目访问订单列表,在 rdm 里查看 Redis 缓存,有 product::123 说明缓存成功。
更新缓存
在需要更新缓存的方法上加注解: @CachePut(cacheNames = "product", key = "123")
注意
-
cacheNames 和 key 要跟 @Cacheable() 里的一致,才会正确更新。 -
@CachePut() 和 @Cacheable() 注解的方法返回值要一致
删除缓存
在需要删除缓存的方法上加注解:@CacheEvict(cacheNames = "product", key = "123") ,执行完这个方法之后会将 Redis 中对应的记录删除。
其他常用功能
-
cacheNames 也可以统一写在类上面, @CacheConfig(cacheNames = "product") ,具体的方法上就不用写啦。
@RestController
@CacheConfig(cacheNames = "product")
public class ProdectController {}
Key 也可以动态设置为方法的参数
@GetMapping("/detail")
@Cacheable(cacheNames = "product", key = "#id")
public Product detail(@RequestParam("id") Integer id){
if (id==1){
return new Product(1,"电冰箱",20d);
}else if (id==2){
return new Product(2,"洗衣机",30d);
}else {
return new Product(3,"彩电",40d);
}
}
-
如果参数是个对象,也可以设置对象的某个属性为 key。比如其中一个参数是 user 对象,key 可以写成 key="#user.id" -
缓存还可以设置条件。 设置当 openid 的长度大于3时才缓存
@GetMapping("/detailOnCondition")
@Cacheable(cacheNames = "product", key = "#id", condition = "#id > 2")
public void detail(@RequestParam("id") String id){
System.out.println("id是"+id);
}
还可以指定 unless 即条件不成立时缓存。#result 代表返回值,意思是当返回码不等于 0 时不缓存,也就是等于 0 时才缓存。
@GetMapping("/detailOnConditionAndUnless")
@Cacheable(cacheNames = "product", key = "#id", condition = "#id > 2", unless = "#result!= 0")
public Integer detailOnConditionAndUnless(@RequestParam("id") Integer id){
if (id==3){
return 0;
}else {
return 1;
}
}
|