Springboot整合redis注解法做缓存
一般来说数据库的访问量不多的话,是完全不需要实现缓存的,但一旦用户多了起来,你的数据库又不支持缓存机制,及很容易发生宕机,所以我们用到了springboot集成的redis缓存来解决这个问题
主要Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
一.由于使用了springboot项目,我们在导入redis时的配置如下
cache:使用redis
redis里面的参数
host:redis的ip,这里我们用的本地ip
port:redis使用的端口号
password:初始密码为无
pool:连接池配置
max-active:连接池最大连接数(使用负值表示没有限制)
max-wait:连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle:连接池中的最大空闲连接
timeout:连接超时时间(毫秒)
database:使用的db几数据库
spring:
datasource:
name: songs
url: jdbc:mysql://localhost:3306/songs?characterEncoding=utf-8&useSSL=false
username: root
password: kaikai
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
application:
name: VIEW-SERVICE
cache:
type: REDIS
redis:
host: 127.0.0.1
port: 6379
password:
pool:
max-active: 100
max-idle: 10
max-wait: 100000
lettuce:
shutdown-timeout: 0
timeout: 5000
database: 0
在你开启项目上加上:@EnableCaching
二.实体类及其他类展示
userDO类
此处!!!一定要在你缓存的返回的类型加上序列化
看不懂的先往下看!
就是这个
userModel
controller
/**
* 通过userId查找user信息(详细)
* @param id
* @return
* @throws BusinessException
*/
@GetMapping("detail/{id}")
public UserModel getUserById(@PathVariable("id") Integer id)throws BusinessException {
UserModel userModel=userService.getUserById(id);
String str=jsonObject.toJSONString(userModel);
return userModel;
}
serviceimpl实现类
@Override
@Cacheable(cacheNames="user", key="#id")
public UserModel getUserById(Integer id) {
System.out.println("没缓存!");
UserModel userModel=new UserModel();
UserDO userDO=userDOMapper.selectByPrimaryKey(id);
BeanUtils.copyProperties(userDO,userModel);
return userModel;
}
此处就是我们开启缓存的地方我们加上了Cacheable()缓存注解
由于我们返回的是userModel类型,所以要在userModel这个类上实现implements Serializable序列化接口,不然是存不到redis里面的,redis里面都是键值对类型的string
接下来我们来讲一下注解法实现缓存
三.验证及缓存注解法详解
1.验证
首先我们先来验证一下上面代码的缓存
之前我们在serviceimpl里面的方法加了一句:System.out.println(“没缓存!”);
意思是如果没用缓存就回打出这一句话,用了缓存机制就不会打出这一句话
接下来我们在postman里发个请求
确实返回了数据,没有报错,那我们来看看redis数据库里面放了些什么
确实放进去了,那我们再请求另一条数据看看
确实也放进去了,而且是按照一定规则放进去的,接下来我们多次请求这两条数据,
发现控制台只打出了2句话
这就验证了,缓存要是没消失,就不会重复去数据库去取,而是直接返回缓存里的东西
2.注解
@Cacheable
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
- value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了
- key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = “#p0”):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
- condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = “#p0”, condition = “#p0.length() < 3”),表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。
- unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
- keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
- cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用
- cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。
@CachePut
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
参数 | 解释 |
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 |
@CacheEvict
参数 | 解释 |
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 |
allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 |
beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 |
@CacheConfig
所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法写别的名字,那么依然以方法的名字为准。
@CacheConfig是一个类级别的注解。