Spring Cache是一个框架,实现了基于注解的缓存功能。只需要简单地加一个注解,就能实现缓存功能
Spring Cache提供了一层抽象,底层可以切换不同的缓存实现,例如:
1.EHCahce
2.Chffeine
3.Redis
需要导入的maven坐标
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Spring Cache的常用注解
注解 | 说明 |
---|---|
@EnableCaching | 开启缓存注解功能,通常加载启动类上 |
@Cacheable | 在方法执行前先查询缓存中是否有数据,如果有数据,直接返回缓存中的数据;如果没有缓存数据,调用方法并将返回值放到缓存中 |
@CachePut | 将方法的返回值放到缓存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
第一步 先开启注解缓存 @EnableCaching
@Slf4j
@SpringBootApplication
@EnableCaching
public class CacheDemoApplication {public static void main(String[] args) {SpringApplication.run(CacheDemoApplication.class,args);log.info("项目启动成功...");}
}
第二步 使用将数据加入缓存注解 @CachePut()
@PostMapping
//如果使用Spring Cache缓存数据,key的生成:"cacheName::key"-->"userCache::2"
@CachePut(cacheNames = "userCache",key = "#user.id")//根据形参名对应获取key
//有多种写法
//@CachePut(cacheNames = "userCache",key = "#result.id")//返回值对应
//@CachePut(cacheNames = "userCache",key = "#p0.id")//根据第几个形参对应,p0第一个形参,p2、p3
//@CachePut(cacheNames = "userCache",key = "#a0.id")//也是一样
//@CachePut(cacheNames = "userCache",key = "#root.args[0].id")//也是一样
public User save(@RequestBody User user){userMapper.insert(user);return user;
}
具体解释看注解的源码注释
/*** Spring Expression Language (SpEL) expression for computing the key dynamically.* <p>Default is {@code ""}, meaning all method parameters are considered as a key,* unless a custom {@link #keyGenerator} has been set.* <p>The SpEL expression evaluates against a dedicated context that provides the* following meta-data:* <ul>* <li>{@code #result} for a reference to the result of the method invocation. For* supported wrappers such as {@code Optional}, {@code #result} refers to the actual* object, not the wrapper</li>* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for* references to the {@link java.lang.reflect.Method method}, target object, and* affected cache(s) respectively.</li>* <li>Shortcuts for the method name ({@code #root.methodName}) and target class* ({@code #root.targetClass}) are also available.* <li>Method arguments can be accessed by index. For instance the second argument* can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments* can also be accessed by name if that information is available.</li>* </ul>*/
String key() default "";
第三步 使用从缓存中获取数据的注解 @Cacheable()
@GetMapping
//拼接key之后从缓存中获取,有则直接返回,没有的话就会通过反射执行这个方法获取数据,并且加入到缓存中
@Cacheable(cacheNames = "userCache",key = "#id")
public User getById(Long id){User user = userMapper.getById(id);return user;
}
此时,执行查询操作会直接先去redis中查,查得到就直接返回;查不到再执行方法,然后再将返回结果缓存到redis中,因为key都是一样的嘛
第四步 使用清理缓存数据的注解删除指定缓存数据 @CacheEvict
@DeleteMapping
//根据key清理缓存数据
@CacheEvict(cacheNames = "userCache",key = "#id")
public void deleteById(Long id){userMapper.deleteById(id);
}
此时,执行删除操作就会删除对应数据库数据,同时删除redis对应的缓存数据
第五步 使用上面的注解删除所有缓存数据 @CacheEvict + allEntries = true
@DeleteMapping("/delAll")
//allEntries = true:删除cacheNames下的所有键值对,也就是所有缓存数据
@CacheEvict(cacheNames = "userCache",allEntries = true)
public void deleteAll(){userMapper.deleteAll();
}
此时,执行删除操作就会删除对应数据库,同时删除redis所有缓存数据