使用缓存有两个前置步骤
-
在
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;}}