问题描述

今天要完成的业务是,将从Excel中读取的数据转换成相对应的对象,并对其中的字段进行验证,并根据其中的租约号/造箱合同号,从数据库中查询对应数据进行填充。而数据库中没有的字段则从基础代码的数据库表中根据Excel中传入的name属性来填充其对应的code属性。因为用户在录入时不可能去录入code,对于用户来讲,name才是更人性化的标识。

画个简图大概是这样,其中又有很多判断就没有再细分

image-20200914144843745

遇到的问题

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.


ALL WILL BE CLEAR