之前项目有一个需求:开发首页的各类分析数据,一共有五个图表需要进行分析,因为首页是最频繁访问的,每个接口都要求响应速度很快,所以一定要写到缓存中,然后在每天走定时任务的时候更新当天的新数据
首页数据是这样展示的:有两个下拉单选框作为筛选项,部门和导购
因为部门下有n个导购,单选导购可以筛选出这个导购下的分析图表,单选部门可以筛选部门下所有导购的图表
所以设计上每个图表的接口都会存在一个hash结构下,并拼上日期,以其中一个图表为例data_portrait_member_id_2021-12-01
同时需要再写一个缓存,记录当天的日期data_date_time
hash里面存的key就是对应的导购id,value是里面算出来的图表,多个key就能组成部门的图表了
写入的代码实现
redisUtils.hmSet(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime())
,wechatQuery.getWorkerId().toString()
,JSON.toJSONString(portraitVO));
所有的缓存单独存一个key,这里部门就不用拿出来遍历去算
if (isAll){
redisUtils.hmSet(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime())
,"all"
,JSON.toJSONString(portraitVO));
}
取缓存
Object result = redisUtils.hmGet(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime())
,"all");
if (result!=null){
return JSONObject.toJavaObject(
JSONObject.parseObject(result.toString()),PortraitVO.class);
}
部门取缓存用到hmGetList取出list遍历算部门
List<Object> portraitVOList = redisUtils.hmGetList(Constant.DATA_PORTRAIT_MEMBER_ID + sf.format(c.getTime()),memberIds);
if (portraitVOList.size()>0){
for (Object o:portraitVOList) {
if (o!=null){
PortraitVO portraitVO = JSONObject.toJavaObject(
JSONObject.parseObject(o.toString()),PortraitVO.class);
//-----------------其他代码实现
}
}
}
封装了下multiGet
public List<Object> hmGetList(String key, List<String> hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
Collection collection = hashKey;
return hash.multiGet(key, collection);
}
最后再说一下data_date_time
缓存的作用
每次进方法的时候调用一下
Calendar c = getDataNowOrYesterday();
目的是为了今天凌晨的时候跑定时任务,先访问缓存,先看昨天的key是否还存在,存在则返回false,然后Calendar调用昨天的缓存
public Calendar getDataNowOrYesterday(){
Calendar c = Calendar.getInstance();
if (!isDataNow()){
c.add(Calendar.DAY_OF_YEAR, -1);
}
return c;
}
public boolean isDataNow() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, -1);
//今天访问缓存,先看昨天的key是否还存在,存在则返回false
if (redisUtils.get(Constant.DATA_DATE_TIME) != null
&& redisUtils.get(Constant.DATA_DATE_TIME).equals(sf.format(c.getTime()))) {
return false;
} else {
return true;
}
}
这样就确保了即使用户凌晨在跑定时任务的时候访问系统,只会访问到昨天的图表,而在今天的缓存写入之后,更新data_date_time
,读到今天的新图表,确保了隔离