Redis缓存其实运用到的也是AOP(面向切面)原理

spring boot redis存储对象数据 spring boot redis cache_java

以程序为例,tomcat里是我们的java应用,第一步会先从redis获取,如果没有,就会从db上面获取,如果取出了,他还会把取出的东西重新写回redis

使用缓存的步骤:

 一、在SellApplication上添加注解@EnableCaching

如果你想引入缓存的话,可以在pom上直接写入以下代码

spring boot redis存储对象数据 spring boot redis cache_redis_02

 

 

二、在BuyerProductController.list()方法上添加注解@Cacheable(cacheNames = "product", key = "123")

那么他第一次就会从数据库读出,但从第二次开始,就不会调用数据库的方法,反而是从redis缓存中读出数据。

  三、更新数据库的数据时,修改缓存中的数据

在调用数据库更新方法时,比如SellerProductController.save()方法时,添加注解@CachePut(cacheNames = "product", key = "123")

 A、@Cacheable()注解第一次访问的时候会访问到方法里面的内容,在BuyerProductController.list()方法中会返回ResultVO这个对象,这个时候会设置redis,redis存储的就是ResultVO这个对象,

但下一次再访问的时候就不会进入方法里。而@CachePut()这个注解,每一次还是会执行方法,而每一次执行完后,它会把返回的对象塞回到redis。

但是此时问题来了,因为SellerProductController.save()返回的对象是ModelAndView,而不是ResultVO,但是我们要的就是ResultVO(需要持久化)。此时我们可以用另外一个注解,

用一个可以删除redis缓存的注解,叫做@CacheEvict(),在访问SellerProductController.save()方法之后,她会清除redis缓存,那么接下来再次访问BuyerProductController.list()方法时,他就会先进入

方法里执行数据库方法,生成缓存,然后第二次开始就不进入方法体内,直接使用缓存。

B、这时问题来了,如果我就是要用@CachePut()这个注解呢?那返回的对象肯定要跟之前的对象一样才行啊。那我们找两个返回同样对象的方法,就是ProductServiceImpl.findOne()和

ProductServiceImpl.save(),他们返回的都是ProductInfo对象。所以先让ProductInfo继承Serializable接口,如下图所示:

spring boot redis存储对象数据 spring boot redis cache_缓存_03

spring boot redis存储对象数据 spring boot redis cache_缓存_04

如果要同时用到上面两个注解,那么要确保两个方法返回的对象是相同的。

另外一点,注解中的key是不可以删除的,而且要一致才行,因为如果没写或没值,那么她会默认用传递的参数,那么就会导致参数不一致。 

C、还有一种写法,并且只写一次就可以了。

 

spring boot redis存储对象数据 spring boot redis cache_数据库_05

此外,key可以动态注解,称为spel表达式。

 

spring boot redis存储对象数据 spring boot redis cache_redis_06

另外,注解中还有其他表达式,比如condition(判断是否成立)

 

spring boot redis存储对象数据 spring boot redis cache_java_07

还有根据结果进行缓存的unless表达式,

spring boot redis存储对象数据 spring boot redis cache_redis缓存_08