简介
当我们需要展示数据的时候,后台会根据需要从服务器中获取数据,但是频繁的请求数据库会对服务造成压力,于是我们引入了缓存这个概念。
当我们引入缓存后,在调用一个缓存方法时,会根据相关信息和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回,从而避免频繁访问数据库的情况。
基本注解
注解 | 解释 |
---|---|
@EnableCaching | 开启基于注解的缓存 |
@CacheConfig | 统一配置本类的缓存注解的属性 |
@Cacheable | 第一次调用方法后都将返回值存入缓存,下次则请求直接调用缓存 |
@CachePut | 每次调用方法后都将返回值存入缓存,用于缓存更新 |
@CacheEvict | 清除缓存 |
@Caching | 组合注解,即给一个方法同时设置多个缓存方案 |
@Cacheable/@CachePut/@CacheEvict 主要的参数
属性 | 解释 |
---|---|
value/cacheNames | 缓存区域的名称,必须指定至少一个 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写, 如果不指定,则缺省按照方法的所有参数进行组合 例如:@Cacheable(key=”#id”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false, 只有为 true 才进行缓存/清除缓存 例如:@Cacheable(condition=”#user != null”) |
unless | 当条件结果为TRUE时,就不会缓存。 例如@Cacheable(unless=”#user == null”) |
allEntries (@CacheEvict ) |
是否清空对应缓存区域所有缓存内容,默认为 false |
beforeInvocation (@CacheEvict) |
是否在方法执行前就清空缓存,默认为 false,即如果方法没有执行完,或者抛出异常就不会清空缓存 |
使用
添加依赖
在springboot的pom文件添加如下依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
启用注解
在启动类里添加@EnableCaching注解开启缓存
@EnableCaching//开启缓存
@MapperScan(basePackages = "com.huang.mapper")
@SpringBootApplication
public class SpringbootCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCacheApplication.class, args);
}
}
注意:默认提供的缓存实现方式是map集合
使用缓存
1 在要缓存结果的方法上添加@Cacheabl注解
/*
* @Cacheabl
* 开启缓存,将方法结果存入缓存,再次请求同样的数据时直接从缓存中调用,不再调用方法
* 属性:
* value/cacheName:指定缓存名字
* key:指定缓存数据的键值对的key,默认为方法参数中的值
* 也可用sqEl表达式
* Condition:指定缓存执行的条件
* unliss:指定缓存不执行的条件
* sync:指定缓存是否使用异步模式,默认同步,若异步则不支持unless
* */
@Override
@Cacheable(cacheNames = "dept",key = "targetClass")
public List<Dept> findAll() {
System.out.println("全查!");
return mapper.selectAll();
}
2 在要更新缓存的方法上添加@CachePut注解
/*
* @CachePut
* 调用方法后,再把返回值放入缓存
* 属性与cacheable基本相同
* 由于总是执行方法后才操作缓存,在key等属性可以调用#result返回值
* 设置key与@cachable相同可以重写缓存里的数据
* */
@Override
@CachePut(cacheNames = "dept",key = "#root.targetClass")
public List<Dept> add(Dept dept) {
System.out.println("增加!");
mapper.insert(dept);
return mapper.selectAll();
}
3 在要更新缓存的方法上添加@CachePut注解
/*
* @CacheEvict
* 清除缓存中的数据
* beforeInvocation
* 默认值为false,即默认清除缓存在方法后执行,若出现异常则缓存不清除。为true则相反
* */
@CacheEvict(cacheNames = "dept",key = "#root.targetClass",beforeInvocation = false)
@Override
public void delete(Integer deptno) {
System.out.println("删除!");
mapper.deleteByPrimaryKey(deptno);
}
4 在有复杂缓存策略的方法上添加@Caching注解
/*
* @caching
* 组合注解,三种注解以每种可有多个,以数组形式存储
* */
@Caching(
cacheable = {
//添加一个缓存
@Cacheable(value = "dept",key = "#deptno")
},
put = {
//更新一个缓存
@CachePut(value = "emp",key = "#root.targetClass")
},
evict = {
//清除一个缓存
@CacheEvict(value = "person",key = "#deptno")
}
)
@Override
public Dept findById(Integer deptno) {
return null;
}
5 当一个类里多个方法的缓存有重复配置,可以在类上使用@CacheConfig注解
//使用@CacheConfig统一cacheName,如果在方法上仍写了value,则该方法值仍以value为准
@CacheConfig(cacheNames = "dept")
@Service
public class DeptServiceImp implements DeptService {
@Resource
private DeptMapper mapper;
@Override
@Cacheable(key = "targetClass")
public List<Dept> findAll() {
System.out.println("全查!");
return mapper.selectAll();
}
@Override
@CachePut(key = "targetClass")
public List<Dept> add(Dept dept) {
System.out.println("增加!");
mapper.insert(dept);
return mapper.selectAll();
}
@CachePut(key = "targetClass")
@Override
public List<Dept> delete(Integer deptno) {
System.out.println("删除!");
mapper.deleteByPrimaryKey(deptno);
return mapper.selectAll();
}
}