在开发业务代码时经常会碰到通过导入excel来批量新增数据的功能,但一般这样做当excel文件过大,要插入的记录过多时,就会导致导入处理速度慢,毕竟做的数据库操作过多,且在插入数据库时需先做数据校验处理,解决的思路如下:
问题1:校验重复性的数据库操作过多
解决方法:在操作前先获取批量数据库记录后存入内存中,用于后续做新增还是修改做判断依据,在这里我们把它存进一个map中,
//模拟从数据库查出所有人的记录,其中SfzVO为
List<SfzVO> allSfz=personInfoService.getAllSfz(new HashMap());
Map<String,String> personSfzhs=new HashMap();
if(allSfz!=null && allSfz.size()>0){
for(int i=0;i<allSfz.size();i++){
SfzVO vo= allSfz.get(i);
personSfzhs.put(vo.getSfzh(),vo.getId());
}
}
getAllSfz是mapping的方法,获取了人的身份证和id,其中身份证是为了与excel中的身份证字段对上,从而判断在数据库中是否存在。
问题2:数据库插入/更新的次数随着记录的增多而增多
解决方法:对需要新增、更新的记录先记录起来,当记录累积到一定程度后才执行批量插入/更新逻辑
,在下面的代码中PersonInfoPo为封装的数据库实体对象,届时需要存入数据库,具体代码如下所示:
//初始化批量新增、更新,后续会对这些列表进行批量操作
List<PersonInfoPo> personsUpdate = new ArrayList<>();
List<PersonInfoPo> personsAdd = new ArrayList<>();
//模拟添加数据
personsUpdate.add(new PersonInfoPo("111","张三","441533xxxxxxxxxxxx"));
personsAdd.add(new PersonInfoPo("2222222","张四","441533xxxxxxxxxxxx"))
if(personsAdd.size()>0) {
//批量添加人员信息
List<PersonInfoPo> personTemp = new ArrayList<>();
for(PersonInfoPo tempPo : personsAdd){
personTemp.add(tempPo);
if(personTemp.size()==500){//每500条批量插入一次,为什么不越大越好,因为oracle数据库批量插入语句有长度限制,这里我们弄个500先
personInfoService.saveBatchPerson(personTemp);//使用了mybatic自定义sql,在下面会说到
personTemp = new ArrayList<>();
}
}
if(personTemp.size()>0){
personInfoService.saveBatchPerson(personTemp);
}
}
if(personsUpdate.size()>0){
//批量更新人员信息
List<PersonInfoPo> personTemp = new ArrayList<>();
for(PersonInfoPo tempPo : personsUpdate){
personTemp.add(tempPo);
if(personTemp.size()==500){//每500条批量插入一次,为什么不越大越好,因为oracle数据库批量插入语句有长度限制,这里我们弄个500先
personInfoService.updateBatchPerson(personsUpdate);//使用了mybatic自定义sql,在下面会说到
personTemp = new ArrayList<>();
}
}
if(personTemp.size()>0){
personInfoService.updateBatchPerson(personsUpdate);
}
}
其中saveBatchPerson为mybatis自定义sql,因为要编写批量插入语句,如下所示:
<!--批量导入-->
<insert id="saveBatchPerson" parameterType="java.util.List">
begin
<foreach collection="list" item="item" index="index" separator=" ">
INSERT INTO TB_SUB_IMP_PERSON(ID,NAME,SFZH) VALUES (
#{item.id,jdbcType=VARCHAR},
#{item.name,jdbcType=VARCHAR },
#{item.sfzh,jdbcType=VARCHAR}
);
</foreach>
commit;
end;
</insert>
<!--批量更新人员信息-->
<update id="updateBatchPerson" parameterType="java.util.List">
begin
<foreach collection="list" item="item" index="index" separator=" ">
UPDATE TB_SUB_IMP_PERSON SET
<if test="item.id!= null">
ID=#{item.id,jdbcType=VARCHAR },
</if>
<if test="item.name!= null">
NAME=#{item.name,jdbcType=VARCHAR },
</if>
<if test="item.sfzh!= null">
SFZH=#{item.sfzh,jdbcType=VARCHAR},
</if>
id = #{item.id,jdbcType=VARCHAR}
where id = #{item.id,jdbcType=VARCHAR};
</foreach>
commit;
end;
</update>