下面的代码无法复制粘贴直接使用,主要记录一个性能优化的方法。
若有兴趣,可以认真阅读。
1.首先描述一下Excel导入的步骤
2.当Excel内有大批量的数据时,如何优化校验这个步骤。
我的处理方法是:
* Excel性能优化方法
* 将Excel数据进行划分处理
* 1.根据某一列的属性,把Excel数据划分成多张不同的List数据处理 1->n 一张excel划分成n张excel
* 2.然后根据这一列的属性,从数据库内查询出对应的信息,这一步较原来相比,省去了多次连接数据库查询的操作 原先需要操作m次数据库,现在只需要操作n次
* 3.最后把每一张划分出来的excel表及数据库查询出来的集合信息放进valid方法内
这样对Ecxcel的数据先进行一部分处理,我把这一步叫做归类处理。
这里提供我写的一个分类方法,使用Java 8 的Lamdba 去重
//contionName 这个参数是你想要分类的Excel内的条件,就是某个属性值
//dataItems 是Excel内的所有数据
//最后返回的是一个去重了的List集合,这个集合的用处在于,它的size可以让你知道,你需要划分出几个List/即几个Excel子表
private List<String> getDisONSList(String contionName,List<Map<String,Object>> dataItems){
//获取所有的表对象用户信息
List<String> ONSList = new ArrayList<>();
dataItems.forEach((data)->{
ONSList.add(data.get(contionName).toString());
});
//对表对象用户去重
List<String> disONSList = ONSList.stream().distinct().collect(Collectors.toList());
return disONSList;
}
//底下提供一个我项目内调用的方式
//调用上面那个方法
List<String> disONSList = this.getDisONSList("ONS_OWN",dataItems);
//去重后的list的size即是我们需要校验数据库内信息次数
//通过lamdba filter 方法过滤出对应的所有Excel内的数据,这样就是一张Excel子表
//然后把此子表放入valid这个自己写的校验方法内,这个方法需要自己写,这里不提供。
//AjaxResult 这个也是自己写的工具类。
//最后对这个Excel内子表信息进行一条一条的验证,即可获取验证信息
//生成新的list对象
disONSList.forEach((data)->{
List<Map<String, Object>> allDataItem = getAllDBtableItem(DBTYPE,executeName,data);
//根据当前的表对象用户,过滤出当前该对象所有表信息
List<Map<String,Object>> filterList = dataItems.stream().filter(a -> data.equals(a.get("ONS_OWN").toString().trim())).collect(Collectors.toList());
//然后把该集合和该表对象用户,一同拿去Valid
filterList.forEach((dataItem)->{
AjaxResult ajaxResult = valid(jdbcTemplate,allDataItem ,dataItem,DBTYPE,executeName);
if(!ajaxResult.isSuccess()) {
sb.append(String.format("第%s页 第%s行 ", dataItem.get("sheetNum"),dataItem.get("row")))
.append(ajaxResult.getMessage()).append("</br>");
}
});
});
底下是此次优化的总体框架
此次优化目的在于
1.减少查询数据的次数
2.减少excel内乱序信息,导致的重复低效率查询
总结:
此次优化Excel大批量数据导入的解决痛点在于,对EXCEL进行过滤分类,大大降低了Excel内数据杂乱无章导致的校验效率低下的问题。也减少了访问数据库的连接次数。从N条信息查询N次降低到了去重后的M次查询。