问题描述
今天要完成的业务是,将从Excel中读取的数据转换成相对应的对象,并对其中的字段进行验证,并根据其中的租约号/造箱合同号,从数据库中查询对应数据进行填充。而数据库中没有的字段则从基础代码的数据库表中根据Excel中传入的name
属性来填充其对应的code
属性。因为用户在录入时不可能去录入code,对于用户来讲,name才是更人性化的标识。
画个简图大概是这样,其中又有很多判断就没有再细分
遇到的问题
1、数据过滤问题
首先需要判断这一条数据,数据库中是不是已经存在了,如果存在了则不需要插入并且给前端返回错误。
如果每插入一条数据就从数据库中查询所有并进行比对的话,效率可想而知。
于是我在监听器实例华时就从数据库中查询到所有记录的ID并保存在一个集合中,每次插入一条数据时只需要和这个ID集合进行比对,如果存在则报错,如果不存在则执行下面的步骤,并将这条记录的ID添加进ID集合。
private List<String> getNo() {
List<ContainerBase> containerBaseList = containerBaseMapper.selectAll();
List<String> dataBaseNo = new ArrayList<>();
for (ContainerBase containerBase : containerBaseList) {
dataBaseNo.add(containerBase.getContainerNo());
}
return dataBaseNo;
}
/**
* 数据处理
* @param containerBase
*/
private void dataHandle(ContainerBase containerBase) {
final boolean[] flag = {false};
for (String s : containerNoList) {
if (s.equals(containerBase.getContainerNo())) {
flag[0] = true;
repeatList.add(containerBase.getContainerNo());
break;
}
}
if (!flag[0]) {
containerNoList.add(containerBase.getContainerNo());
list.add(dataFormat(containerBase));
// list.add(containerBase);
}
}
2、数据填充问题
为了给每条记录中的name字段填写对应的code字段,同样也不可能每次填充就去数据库里查。
同样也是在初始化时就将数据库中的基础代码查询出来保存在一个map的List集合中。因为要做到name和code的一一对应关系,map显然是一个比较方便的选择。
然后就是枯燥的 if-else 判断
private List<Map> getAllCode () {
HashMap<String, String> map = new HashMap<>();
3、Bean注入问题
在上面两步中都出现了数据库查询,这就不可避免的需要注入mapper或service来执行查询操作,但由于读取Excel文件是使用的EasyExcel,而它的文档中明确写明了读取数据时使用的监听器不能被Spring接管,否则监听器无法生效。
既然监听器不能放到容器中,那么监听器中的使用的Bean就无法使用@Autowired
注入,而如果使用构造器注入则会让耦合度升高(事实上耦合度会非常高)
那么剩下的办法就是在监听器中使用ApplicationContext
来手动获取Bean(好久没用过的
getBean方法)
public ContainerBaseDataListener(ContainerBaseMapper containerBaseMapper) {
this.containerBaseMapper = containerBaseMapper;
ApplicationContext context = YmlConfigUtil.getContext();
this.businessCodeMapper = context.getBean(BusinessCodeMapper.class);
this.containerLeaseMapper = context.getBean(ContainerLeaseMapper.class);
this.containerCreateMapper = context.getBean(ContainerCreateMapper.class);
this.containerNoList = getNo();
this.allCode = getAllCode();
}
Q.E.D.