前言1.pom加依赖2.在application主程序中开启缓存3.@Cacheable添加缓存3.1 cacheNames3.2 key3.3 keyGenerator3.4 condition3.5 unless3.6 sync4.@CachePut更新缓存5.@CacheEvict:缓存清除6. @Caching组合缓存规则7.@CacheConfig抽取缓存的公共配置 前言缓存原理:CacheManager(缓存管理器)——>Cache缓存组件来实际给缓存中存取数据 默认使用的是ConcurrentMapCacheManager==ConcurrentMapCache;将数据保存在ConcurrentMap中。实际开发中使用缓存中间件:redis,memcached,ehcache;以下内容是默认模式: 1.pom加依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId></dependency> 2.在application主程序中开启缓存就是加这个@EnableCaching @SpringBootApplication@EnableCachingpublic class CacheApplication { public static void main(String[] args) { SpringApplication.run(CacheApplication.class, args); }} 3.@Cacheable添加缓存在调用底层数据库的方法上加@Cacheable参数对结果进行缓存,一般就是在service层。运行时机:@Cacheable是先从缓存中根据key查,缓存中没有的话才走方法。 @Cacheable(cacheNames = {"emp"})public Employee getById(Integer id){ return employeeDao.getEmpId(id);} 解释:@Cacheable注解就可以对该方法返回的结果进行缓存常用的一些属性设置: 3.1 cacheNames或者可以直接写value,指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存 3.2 key缓存数据使用的key;可以用它来指定。 默认是使用方法参数的值编写SpEL; #id;参数id的值#a0 #p0 #root. args[0]例子:getEmp[2] @Cacheable(value = {"emp"},key = "#root.methodName+'['+#id+']'") public Employee getById(Integer id){ return employeeDao.getEmpId(id); }} 3.3 keyGeneratorkey的生成器;可以自己指定key的生成器的组件idkey/keyGenerator:二选一使用同样也是例子:getEmp[2] 效果如下(跟上面是一样的)写法: 先写一个配置类 ```java @Configuration public class MyCacheConfig { @Bean(“mykeyGenerator”) public KeyGenerator keyGenerator(){ return new KeyGenerator() { /** * 生成目标key * @param target * @param method * @param params * @return */ @Override public Object generate(Object target, Method method, Object... params) { return method.getName()+"["+ Arrays.asList(params) +"]"; } }; } } 2. service里引用```java@Cacheable(value = {"emp"},keyGenerator = "mykeyGenerator") public Employee getById(Integer id){ return employeeDao.getEmpId(id); } 3.4 condition指定符合条件的情况下才缓存例子:condition = “#a0>1” 就是说当一个参数大于1的时候才进行缓存 //这里的#a0也就是#id @Cacheable(value = {"emp"},keyGenerator = "mykeyGenerator",condition = "#a0>1") public Employee getById(Integer id){ return employeeDao.getEmpId(id); } 3.5 unless否定缓存,可以理解成如果不是这样就进缓存。如果是这样就不进缓存例子:unless = “#id ==2” 当传过来的id值是2的话就不进缓存。 @Cacheable(value = {"emp"},keyGenerator = "mykeyGenerator",condition = "#a0>1",unless = "#id ==2") public Employee getById(Integer id){ return employeeDao.getEmpId(id); } 3.6 sync是否使用异步模式。默认是false。当使用sync注解的时候,unless就不能用了。 4.@CachePut更新缓存既调用方法,又更新缓存数据;修改了数据库的某个数据,同时更新缓存运行时机:1. 先调用目标方法;2.将目标方法的结果缓存起来。 @Cacheable(value = {"emp"},key = "#id") public Employee getById(Integer id){ System.out.println("查询员工"); return employeeDao.getEmpId(id); } @CachePut(value = {"emp"},key = "#employee.id") public Employee updateEmp(Employee employee){ System.out.println("更新员工"); employeeDao.updateEmp(employee); return employee; } @GetMapping("/updateEmp") public Employee updateEmp(Employee employee){ return employeeService.updateEmp(employee); }} 5.@CacheEvict:缓存清除 @CacheEvict(value = "emp",key = "#id") public void deleteEmp(Integer id ){ System.out.println("删除员工");// employeeDao.deleteEmp(id); } @GetMapping("/deleteEmp/{id}") public String delete(@PathVariable("id")Integer id){ employeeService.deleteEmp(id); return "success"; } 6. @Caching组合缓存规则例子:根据名字查询员工后,让根据ID和根据email查询的时候也有缓存。 @Caching( cacheable = { @Cacheable(value = "emp",key = "#name") }, put = { @CachePut(value = "emp",key = "#result.id"), @CachePut(value = "emp",key = "#result.email") } ) public Employee getByName(String name){ return employeeDao.getByName(name); } @GetMapping("/getByName/{name}") public Employee getByName(@PathVariable("name") String name){ return employeeService.getByName(name); } 7.@CacheConfig抽取缓存的公共配置例子:service层中有很多缓存名字都是一样的,每个方法上都写一遍的话很麻烦。所以抽取个公共的比较好。 @CacheConfig(cacheNames = "emp")//加到service类上 @Caching( cacheable = { @Cacheable(/*value = "emp",*/key = "#name") }, put = { @CachePut(/*value = "emp",*/key = "#result.id"), @CachePut(/*value = "emp",*/key = "#result.email") } ) public Employee getByName(String name){ return employeeDao.getByName(name); } 有了@CacheConfig,上题中的value = “emp”,就可以直接省略不写。