导入批量数据将数据分组
在导入数据操作中,我们通常会计入日志,有必要的话还会显示在前台告知导入者共计导入或新增或更新了多少
条数据,而在此之前我们根据导入数据的编码来查询数据库的本来存不存在,再来匹配数据是更新还是新增,一般我们新手做法是用一个for循环去查询,这样是可以解决问题,但这样查一次就会连接一次数据库,对其性能损耗很大,所以一次查询出结果是很有必要的.
我这是被安排的任务是完成批量导入数据功能能,但导入的数据如果有编码重复的,就在前台给用户选择哪些是要覆盖的,哪些不导入.这里的重点就是”查一次”.
流程图
哈哈,第一次用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);
}