开发者学堂课程【SpringBoot 快速掌握 - 高级应用:自定义 CacheManager】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/613/detail/9297
自定义 CacheManager
内容介绍:
一、缓存数据的原理
二、员工的数据缓存
三、部门的数据查询及缓存
四、用编码的方式获取缓存数据
一、缓存数据的原理
CacheManager===Cache 缓存组件给实际缓存存取数据。将自动配置的报告打开,启动整个应用,自动配置报告里有许多缓存配置类,默认开启的是 simpleCacheConfiguration ,引入 Redis 后搜素,
发现RadisCacheConfiguration 可以匹配上,而 simpleCacheConfiguration 不会匹配上,这是因为 simpleCacheConfiguration 起作用的条件是容器中没有 Cachemanager 。引入 redis 以后,相应的条件就满足了,RedisTemplate也可以使用了。
Redis配置中如果没有 Cachemanager ,就相当于完成判断并在容器中放置一个缓存管理器(RedisCachemanager)。
二、员工的数据缓存
1、引入 redis 的 starter
容器中保存的是 RediscacheManager;
2、RedisCacheManager 创建 RedisCache
RedisCache作为缓存组件,通过操作 redis 缓存数据;
3、默认保存数据 k-v 都是 object:利用序列化保存
启动应用进行测试,缓存1号员工的信息,发出请求 emp1 ,第一次查询一号员工,此时控制台打印了 SQL 语句,表明查询了数据库,刷新后再次查询发现没有查询数据库,说明已经缓存了,且存在于 redis 中,在 redis 中显示的是序列化后的结果。
4、自动保存为 json 数据
引入 redis 的 starter ,cacheManager 变为 redisCacheManager。redisCacheManager 是由 redisConfiguration 创建的,默认创建的redisCacheManager 操作 redis 的时候使用的是 RedisTemplate<0bject, 0bjec> ,而 RedisTemplate<0bject, 0bjec> 利用 redis auto configuration 创建的,它默认使用的序列化机制是 JDK 。
5、自定义 CacheManager
在 redis 配置创建一个 CacheManager。输入 public redisCacheManager ,称作employeeCacheManager,在 redisCacheConfiguration 中新建一个redisCacheManager,即可将自定义的 CacheManager 放在容器中。
将 template 传进来,在配置类里将新建内容复制过来,再输入 return CacheManager 即可。
通过观察可以发现系统默认缓存管理器的条件是没有 CacheManager ,而我们创建的含有 CacheManager ,启动并刷新后查询员工一号张三,
第一次查询了数据库,
刷新后第二次没有查数据库,在 redis 里发现 emp 中有一个前缀 emp:1 ,它的值是通过 json 的方式序列化过来的,这个前缀是因为默认使用的是传输参数(ID)值,而在这里配置了 redisCacheManager ,我们设置了一个使用前缀,这样就会默认将 Cache name 作为 key 的前缀。
三、部门的数据查询及缓存
1、部门数据查询
创建 Deptservice,引用 @Service,写一个查询方法,把 DepartmentMapper 注入进来,让它来操作数据库。
通过 public Department getDepById 传入 Integer ID,创建并调用 DepartmentMapper.getDepById,
创建出来以后要标记上 SQL 语句 @Select("SELECT * FROM department WHERE id = #{id}"), Service 中将查询结果返回到 department 中。
2、部门数据缓存
标记可缓存的注解 @Cacheable(cacheNames = "dept"),输入 System.out-println ("查询部门"+id),启动后测试,查询部门并加上 controller,为了测试方便新建一个 class,命名为 DeptController。
标记注解 @RestController 并输入以下代码:
public class Deptcontroller {
@Autowired
DeptService deptService;
@GetNapping("/dept/{id}"
)
public Department getDept(@PathVariable("id") Integer id){
return deptService.getDeptById(id);}
}
重新启动进行测试,查询第一次有结果,刷新后查看第二次,redis中存有dept 数据,且含有1号部门的json数据。第二次查询通过缓存进行,但是不能读取 json 数据。
这是因为需要映射的数据是反映员工的,但是我们查出来的数据是部门的,而使用的redisCacheManager是用来缓存员工数据的,所以缓存的数据只能存入 redis ,但不能在第二次缓存查询中反序列化回来。
因此我们需要新建一个部门的缓存管理器,
代码如下:
@Bean
public RedisCacheManager deptCacheManager(RedisTemplate<Object,Department> deptRedisTemplate)
RedisCacheManager cacheManager = new RedisCacheManager(deptRedisTemplate);
此时,部门与员工分别有了各自的CacheManager ,进行部门缓存检测时,将deptCacheManager设为默认缓存管理器(通过标记注解@Primary),同理进行员工缓存检测时将employeeCacheManager设为默认缓存管理器。
重新启动后发现存储了部门数据且在第二次查询时反序列化成功
四、用编码的方式获取缓存数据
使用缓存管理器得到缓存,进行api调用
利用编码查处部门,向给缓存中放入redis Cachemanager,即将Cache manager注入进来,redis Cachemanager有很多类,我们就注入deptCachemanager,主注入部门的缓存管理器。
以获取部门缓存数据为例
核心代码如下:
@Autowired
DepartmentMapper departmentMapper;
@Qualifier("deptCacheManager")
@Autowired
RedisCacheManager deptCacheManager;
指定过来以后,通过:
Cache dept = deptCacheManager.getCache( name:"dept");
dept.put( "dept: 1" ,department); 获取某个缓存。