题外话
先解释下标题。整个报表业务层核心:多个集合数据合并计算。经过自己整合设计优化,核心代码使用了java8函数一行代码实现了。
实操步骤
文章报表功能(一)背景及优化设计对报表的背景和具体设计思路进行讲解,下面将讲讲具体实践操作中的几个重点。
1.数据同步工具选择
选择阿里的datax工具。
优势:简单易上手;劣势:每个预存储表对应一个脚本(例如:要同步得到天、时、分表,需要写三个脚本)。
选取理由:上手时间成本低,且能够满足报表同步数据的功能需求。
2.如何设计天、时、分预存储表
这个得结合各自公司项目的具体业务场景去设计,没办法细聊。不过可以谈谈自己的考虑思路:
- 尽量梳理出各个报表业务中共性数据统计到预存储表中(目的:减少预存储表的数量,提高复用性)。
- 天、时、分表同步脚本最好都基于原始数据表。而不是天表数据从时表同步,时表数据从分表同步。理由:应对工具宕机、脚本未执行等意外情况以及修改维护方便考虑。
- 预存储表必须添加脚本执行时间、截取数据的区间时间(这个时间就是用来在查询时候保证三个表数据不重复的时间临界值)。
3.脚本中sql的撰写
这是个复杂点,主要体现在业务上,其实相当于将原始数据形成二次的业务数据。脚本如何写已在报表功能(二)-Windows下dataX使用中贴了部分示例代码。
4.java8在代码层应用
**第一步:**天、分、实时表取出数据,然后用java8中map转化为同类型对象元素的集合数据。(优化空间:jpa框架、mybatis框架都可以实现直接在dao方法层取出的数据用List 接收,省略再转化的过程)
public List<FinancialDTO> reportTest(Date minTime, Date maxTime) {
List<FinancialDTO> financialDTOS = new ArrayList<>();
//天表中数据
List<Map<String, Object>> mapsReportDay = reportDayDao.finacialEarnWarterDayMyself(minTime, maxTime);
//分钟表中数据
List<Map<String, Object>> mapsReportMinute = reportMinuteDao.finacialEarnWarterMinuteMyself(minTime, maxTime);
//实时表中的数据
List<Map<String, Object>> mapsReport = reportDao.finacialEarnWarterMember(minTime, maxTime);
// 使用java8函数转化
List<FinancialDTO> earnWaterDay = mapConvertFinancialDTO(mapsReportDay);
List<FinancialDTO> lostWinEarnDay = mapConvertFinancialDTO(mapsReportMinute);
List<FinancialDTO> earnWaterMinute = mapConvertFinancialDTO(mapsReport);
// earnWaterDay lostWinEarnDay earnWaterMinute 如何合并?
return financialDTOS;
}
public List<FinancialDTO> mapConvertFinancialDTO(List<Map<String, Object>> mapList) {
List<FinancialDTO> collect = mapList.stream().map(map -> {
FinancialDTO financialDTO = new FinancialDTO();
financialDTO.setMap(map);// map中元素set到FinancialDTO中
return financialDTO;
}).collect(Collectors.toList());
return collect;
}
**第二步:**在实体对象FinancialDTO的类中去写赋值、计算、业务逻辑等代码。写的过程中尽量考虑写成通用的方法。
第三步:就是将多个元素类型相同的集合进行合并计算。(ps:经历了三次优化,由最初的几十行代码到几百行代码,根据业务复杂度不等,优化到一行核心代码搞定的节奏)
优化一:两两数据集合合并
优化二:多个集合数据合并
使用java8中,对多个流数据进行合并的方式。
优化三:数据合并
对11个不同集合元素进行合并,且采用了并发方式。
总结
整个优化过程,经历了service层代码量几百行到50行以内的过程,部分代码形成公共方法,部分业务计算代码写到了公共实体中,中间有很多思考点未能表达出来。不过核心的技术实现代码通过图片贴出来了。整体思路应该描述清楚了,对Java8函数不熟悉的可以直接谷歌百度相关教程了解下。
关注下方公众号获取最近更新
更多文章
儿童节礼物【愿历经险阻,归来仍是少年】
报表功能(一)背景及优化设计
log4j2自定义动态配置日志
开关配置springboot定时任务
重复请求的幂等接口设计的思考(一)
我的第一篇微信公号文章
自动化远程登陆操作和传输文件(scp ssh expect)
长按二维码关注,阅读我的程序员故事