导入批量数据一次查询将数据的编码重复的查出来

导入批量数据将数据分组

在导入数据操作中,我们通常会计入日志,有必要的话还会显示在前台告知导入者共计导入或新增或更新了多少
条数据,而在此之前我们根据导入数据的编码来查询数据库的本来存不存在,再来匹配数据是更新还是新增,一般我们新手做法是用一个for循环去查询,这样是可以解决问题,但这样查一次就会连接一次数据库,对其性能损耗很大,所以一次查询出结果是很有必要的.

我这是被安排的任务是完成批量导入数据功能能,但导入的数据如果有编码重复的,就在前台给用户选择哪些是要覆盖的,哪些不导入.这里的重点就是”查一次”.

流程图

Created with Raphaël 2.1.0 解析上传文件得到所有数据,创建HashMap 得到allList(全部数据) 查询sql得到codeExistList(编码存在的数据) 匹配操作(两个集合的code是否相等) 添加入可更新组(将查到数据的id赋给解析后的数据) 存入HashMap,存入session,将编码重复数据传回前台 执行导入操作(导入数据有id的为更新) 添加入可新增组 yes no

哈哈,第一次用MarkDown,强行给自己加戏,见谅!鞠躬!好了接下来是重点!

一次查询全部数据的sql

其实就是in

select * from 表 where code in(item1.code,item2.code,…);

但是!数据库查询里in函数里只最多有999个元素,所以传过来的List参数需要进行处理:
splitList ()方法可以直接拿过去;


@Override
    public List <ReportDisplayInfo> checkCodeIsRepetition (List <ReportDisplayInfo> reportDisplayinfoCodes)
    {
        List <ReportDisplayInfo> result = new ArrayList <ReportDisplayInfo> ();
        List <List <ReportDisplayInfo>> checkCodeIsRepetitionList = new ArrayList <List <ReportDisplayInfo>> ();
        // 数据库的in函数最大能处理999的长度
        checkCodeIsRepetitionList = splitList (reportDisplayinfoCodes, Integer.valueOf (999));
        result = _displayInfoMapper.checkCodeIsRepetition (checkCodeIsRepetitionList);
        return result;
    }

    public static <E> List <List <E>> splitList (List <E> targetList, Integer splitSize)
    {
        if (targetList == null)
            return null;
        Integer size = targetList.size ();
        List <List <E>> resultList = new ArrayList <List <E>> ();
        if (size <= splitSize)
        {
            resultList.add (targetList);
        }
        else
        {
            for (int i = 0; i < size; i += splitSize)
            {
                // 用于限制最后一部分size小于splitSize的list
                Integer limit = i + splitSize;
                if (limit > size)
                {
                    limit = size;
                }
                resultList.add (targetList.subList (i, limit));
            }
        }
        return resultList;
 }

接口方法及mapper文件中的sql

@Param注解请务必加上,不加框架不认识它

 public List <ReportDisplayInfo> checkCodeIsRepetition (@Param ("reportDisplayinfoCodes") List <List <ReportDisplayInfo>> reportDisplayinfoCodes);

由于对参数做了处理变成List <List <E>>类型,所以这变成了双重foreach循环

<select id="checkCodeIsRepetition" resultType="ReportDisplayInfo" parameterType="java.util.List">
        select <include refid="reportDisplayInfo" />
        from BR_ReportDisplayInfo  
        where REPORTDISPALYCODE in 
            <foreach collection="reportDisplayinfoCodes" index="index" item="codeList" separator=" OR REPORTDISPALYCODE IN " >  
                <foreach collection="codeList" index="index" item="info" open="(" separator="," close=")">  
                     #{info.displayCode}  
                </foreach>   
            </foreach>  
    </select>

分组

//allImportData是解析出来的全部数据,temp是数据库中的存在和本次解析数据的code相同的数据
temp = _reportDisplayInfoService.checkCodeIsRepetition (allImportData);
if (CollectionUtils.isNotEmpty (temp))
                {
                    reportDisplayInfoOKButCode = true;
                    // 筛选出可新增数据(分组[可增加数据,选择更新的数据])
                    for (ReportDisplayInfo reportDisplayInfo : allImportData)
                    {
                        int index = 0;
                        for (ReportDisplayInfo reportDisplayInfo2 : temp)
                        {
                            //code匹配上的,加上id属性,以后记日志时可以以此为条件判断它是新增还是更新
                            if (reportDisplayInfo.getDisplayCode ().equals (reportDisplayInfo2.getDisplayCode ()))
                            {
                                reportDisplayInfo.setId (reportDisplayInfo2.getId ());
                                codeRepetitiveData.add (reportDisplayInfo);
                                break;
                            }
                            else
                            {
                                index++;
                                if (index == temp.size ())
                                {
                                    normalData.add (reportDisplayInfo);
                                }
                            }
                        }
                    }
                }
                else
                {
                    normalData.addAll (allImportData);
                }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值