需求说明:
前端某个折线图需要展示历史数据,时效性并不强,主要是看一个大体的趋势。但是数据量较大,为了提高查询速度,采用对数据稀释和引入Redis缓存。
1、首先是获取数据,我获取回来的是List<Map<String, Object>>类型
2、稀释数据,我把它稀释到不超过200条,这样对于一个展示趋势的折线图足够了。
private List<Map<String, Object>> diluentDate(List<Map<String, Object>> list, int volumn) { List<Map<String, Object>> result = new LinkedList<>(); double cof = Math.ceil((double) list.size() / volumn); int i = 0; for (Map<String, Object> m : list) { i++; if (i % cof != 0) { continue; } result.add(m); } return result; }
short volumn = 200; // 具体使用,先判断获取数据list的大小,大于就稀释,不大于就直接返回 List<Map<String, Object>> result; if (list.size() > volumn) { result = diluentDate(list, volumn); } else { result = list; }
3、缓存服务
Redis中我是都按照简单的key:value模式存储的,需要先定义好key的规则,避免重复
// 按照规则拼接key StringBuilder sb = new StringBuilder(); sb.append(key); // 如果存在,直接返回value Object o = redisUtils.vGet(sb.toString()); if (o != null) { return o.toString(); } // 如果不存在,先去数据库查,再缓存,返回数据 Object s = null; s = dbService.getList(); if (s == null) { return null; } String js; if (s instanceof List) { // 为了前端方便,统一转成JSON格式 js = JSONArray.fromObject(s).toString(); } else { js = JSONObject.fromObject(s).toString(); } redisUtils.saveCache(sb.toString(), js); return s;
4、由于我们并不关心Redis的存储,可以做成异步模式。
注意:异步方法与调用方法不能在同一个类中,否则不生效。
关于Redis工具类的集成可参考我的另一篇博文:https://www.cnblogs.com/SamNicole1809/p/12097440.html
@Async public void saveCache(String key, String value) { vSet(key, value); }