5、Spring Boot缓存
2021-03-14 16:41
package com.hosystem.cache.service;
import com.hosystem.cache.bean.Employee;
import com.hosystem.cache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
@Service
@CacheConfig(cacheNames = "emp")
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
/**
* 将方法的运行结果进行缓存;下次在调用相同的数据,直接从缓存中获取,不再调用方法;
*
* CacheManager管理多个cache组件,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字
* 工作原理:
* 1.自动配置类:CacheAutoConfiguration
* 2.缓存配置类:GenericCacheConfiguration、JCacheCacheConfiguration、EhCacheCacheConfiguration、HazelcastCacheConfiguration、InfinispanCacheConfiguration、CouchbaseCacheConfiguration、RedisCacheConfiguration、CaffeineCacheConfiguration、SimpleCacheConfiguration、NoOpCacheConfiguration
* org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
* org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
* org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
* org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
* org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
* org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
* org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
* org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
* org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration
* org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
* 3.配置类默认生效:SimpleCacheConfiguration
* 4.给容器中注册了一个cacheManager:ConcurrentMapCacheManager
* 5.可以获取、创建ConcurrentMapCache类型的缓存组件;它的作用是将数据保存在ConcurrentMap中
*
* @Cacheable 运行流程:
* 1.方法运行之前,先去查找Cache(缓存组件),按照cacheNames指定的名字获取;(CacheManager先获取相应的缓存)第一次获取缓存如果没有该缓存则会自动创建
* 2.去Cache中查找缓存的内容,使用一个key,默认为方法的参数;
* (1).key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key
* (2).默认使用SimpleKeyGenerator生成key默认策略:若无参数,key = new SimpleKey();|如果有单个参数,key=参数值;|如果有多个参数,key = new SimpleKey(params);
* 3.若为查找到缓存就调用方法
* 4.将方法返回的结果,放入缓存中
* @Cacheable 标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key查找缓存,如果缓存不存在,则运行方法并将结果放入缓存
* 核心:
* 1.使用CacheManager[ConcurrentMapCacheManager]按照名字获取cache[ConcurrentHashMapCache]组件
* 2.key使用keyGenerator生成,默认是SimpleKeyGenerator
*
* 属性:value、cacheNames、key、keyGenerator、cacheManager、cacheResolver、condition、unless、sync
* value/cacheNames:指定缓存组件的名字
* key:缓存数据使用的key,可以用它指定参数。默认是使用方法参数的值
* SpEL: #id:参数id的值 #a0 #p0 #root.args[0]
* keyGenerator:key生成器;可以指定key生成器组件id;
* 注:keyGenerator和key只能二选一
* cacheManager:指定缓存管理器
* cacheResolver:指定获取解析器
* condition:指定符合条件情况下缓存
* unless:否定缓存;当unless指定条件为true时,方法返回值不会被缓存;可以获取结果进行判断
* sync:是否使用异步模式
*/
//cacheNames = "emp":
//condition = "#id>0":只有当id>0的时候再进行缓存
//condition = "#a0>1":只有当第一个参数>1时候才进行缓存
//unless = "#result==null":当返回结果为空时不进行缓存
//unless = "#a0==2":如果第一个参数的结果为2,则结果不缓存
//key = "#root.methodName+‘[‘+#id+‘]‘"
//keyGenerator = "myKeyGenerator":自定义key
@Cacheable(cacheNames = "emp"/*,condition = "#a0>1",unless = "#a0==2"*/)
public Employee getEmp(Integer id){
System.out.println("查询"+id+"号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
/**
* @CachePut:调用方法同时更新缓存数据
* 修改数据库某个数据 同时更新缓存
*
* 运行时间:
* 1.先调用方法
* 2.将方法的结果缓存起来
*
* 测试步骤:
* 1.查询1号员工;查询到的结果会放在缓存中 key:1 value:lastName:张三
* 2.查询结果照旧
* 3.更新1号员工信息[emp?id=1&lastName=zhangs&gender=0];将方法的返回值也放进缓存中 key:传入的employee对象 值:返回的employee对象
* 4.查询1号员工;查询结果为未更新前的数据[1号员工的信息没有在缓存中更新]
* key = "#employee.id":使用传入参数的员工id进行更新
* key = "#result.id":使用返回后的id
* 注:@Cacheable的key是不能够使用#result
*/
@CachePut(value = "emp",key = "#result.id")
public Employee updateEmp(Employee employee){
System.out.println("update" + employee);
employeeMapper.updateEmp(employee);
return employee;
}
/**
* @CacheEvict:缓存清除
*/
//key = "#id":指定key删除缓存
//allEntries = true:删除缓存中所有数据 默认参数为false
//beforeInvocation=false:缓存的清除是否在方法之前执行 默认是false,即清除缓存操作在方法执行之后执行 如果方法出现异常缓存就不会清除
//beforeInvocation = true:清除缓存操作在方法执行之前执行 如果方法出现异常缓存也会清除
@CacheEvict(value = "emp"/*,key = "#id"*//*,allEntries = true*/,beforeInvocation = true)
public void deleteEmp(Integer id){
System.out.println("delete"+id);
// employeeMapper.deleteEmpById(id);
int i = 10/0;
}
@Caching(
cacheable = {
@Cacheable(value="emp",key="#lastName")
},
put = {
@CachePut(value = "emp",key = "#result.id"),
@CachePut(value = "emp",key = "#result.email")
}
)
public Employee getEmpByLastName(String lastName){
return employeeMapper.getEmpByLastName(lastName);
}
}