需求:
批量导入:excl填写后,导入数据,对于非批量导入时,下拉框字典中选择的列字段,校验:
- 校验列字段是否存在数据库字典中
- 校验列与列之间联级关系 大-中-小-细 生成对应物料编码前缀
思路一:行对比(不可行)
校验是否为字典值:一行看做一个对象,再从对象中拿到 第一列 的属性值,然后去和数据库字典值对比,看是否在字典中
校验联级关系:如果在字典中,假设有100行导入,有4列,需要对比校验 字典类型4个,每个字典类型里面10个字典值,
校验1条就可能最多循环 10x10x10x10 = 10000 一万次
校验100条数据就可能循环 100x10000 = 1000000 一百万次
这样系统会非常卡,所以这个思路不可行
校验导入List数据伪代码:
// 4层for循环,校验联级关系是否正确
for ( importList 中的 每个对象){ // 导入10行,就要循环10次
// 第1行,第1列在字典中 for1
for (standardList1) {
if (row1.column1 在对应 standardList1里面){ // for里面校验,是否在数据库字典值里面
// 第1行,第2列在字典中 for2
for(standardList2){
if (row1.column2 在对应 standardList2里面){
// 第1行,第3列在字典中 for3
for(standardList3){
if (row1.column3 在对应 standardList3里面){
// 第1行,第4列在字典中 for4
for(standardList3){
if (row1.column3 在对应 standardList3里面){
// return 联级关系正确
}
}
}
}
}
}
}
}
}
思路二:列对比(推荐使用,提高效率)
校验是否为字典值:取到 每列 所有数据,判断这列数据 是否在 列数据对应的字典类型-中的字典值里面
校验联级关系:
校验导入List 是否为字典值 伪代码:
// 第一列校验
// 取到第一列 checkList
// 查出第一列 字典类型 对应 数据库中的字典值 standardList
if(CheckNotInStandardDictData(checkList,standardList)方法过滤出不在standardList中的所有项,返回的List<String> notStandardDictData 不为null) {
// 返回错误提示信息
String message = notStandardDictData.stream().collect(Collectors.joining(",", "",";"));
return failureMsg.append("存在非法类型xxx").append(message).toString();
}
}
// 第二列校验
// 取到第二列 checkList
// 查出第二列 字典类型 对应 数据库中的字典值 standardList
if(CheckNotInStandardDictData(checkList,standardList)方法过滤出不在standardList中的所有项,返回的List<String> notStandardDictData 不为null) {
// 返回错误提示信息
String message = notStandardDictData.stream().collect(Collectors.joining(",", "",";"));
return failureMsg.append("存在非法类型xxx").append(message).toString();
}
}
// 第三列校验
// 取到第三列 checkList
// 查出第三列 字典类型 对应 数据库中的字典值 standardList
if(CheckNotInStandardDictData(checkList,standardList)方法过滤出不在standardList中的所有项,返回的List<String> notStandardDictData 不为null) {
// 返回错误提示信息
String message = notStandardDictData.stream().collect(Collectors.joining(",", "",";"));
return failureMsg.append("存在非法类型xxx").append(message).toString();
}
}
// 第四列校验
// 取到第四列 checkList
// 查出第四列 字典类型 对应 数据库中的字典值 standardList
if(CheckNotInStandardDictData(checkList,standardList)方法过滤出不在standardList中的所有项,返回的List<String> notStandardDictData 不为null) {
// 返回错误提示信息
String message = notStandardDictData.stream().collect(Collectors.joining(",", "",";"));
return failureMsg.append("存在非法类型xxx").append(message).toString();
}
}
//这里可以将,每一列的校验方法抽取出来,传进来,checkList,StandardList
List<String> CheckNotInStandardDictData( checkList, standardList){
// 优化点1.对需要校验的List,去重
List<String> newList = checkList.stream().distinct().collect(Collectors.toList());
// 优化点2.对需要校验的List,去空
List<String> result = newList.stream().filter(item -> (StringUtils.isNotEmpty(item) && item.length()>0)).collect(Collectors.toList());
// 校验,拿到checkList的item, 过滤出不包含在standardList中的项,作为错误提示信息返回
return result.stream().filter(item -> !finalStandardList1.contains(item)).collect(Collectors.toList());
}
校验导入List 大-中-小-细 联级关系 伪代码:
//物料编码前缀
String maraPre ="";
Map<String,String> maraPreKeyMap = new HashMap<>();
//获取物料规则前缀
String key =( detail.getZwldl()+ detail.getZwlzl() +detail.getZwlxl() + detail.getZwlsl()).replaceAll(" ", "") ;
if(maraPreKeyMap.containsKey(key)){
maraPre = maraPreKeyMap.get(key);
}else {
maraPre=tnMdMaraTempMapper.selectMatnrPre(detail);
maraPreKeyMap.put(key,maraPre);
}
if(StringUtils.isNull(maraPre)){
failureMsg.append("第" + (i + 1) + "行,获取物料规则前缀失败;").toString();
}else {
detail.setMatnrPre(maraPre);
}