背景
最近项目上需要做一个Excel批量导入一批企业数据到mysql数据库,并对企业名称和企业注册号这两个特定字段去重的需求。
正文
- 首先我会想到的是直接用java去重;先对当前批次的数据进行内部去重,然后和数据库数据进行对比去重,最后批量插入。
1 | //批量插入的SQL |
那么这里和数据库对比的时候会造成频繁的进行交互,我们都知道,这是不好的。
- 又想不那频繁的与数据库进行交互,又能去重,还能批量插入,是否可以直接用一条SQL实现呢?熟悉mysql的人应该知道insert ignore,它是对主键或者唯一索引的字段存在相同数据,则忽略该条数据,否则插入。正好他是复合我们的去重要求的,我们只需对企业名称和企业注册号加上唯一索引就行了。最后再改装成批量的SQL就完美了。
1 | //其实就只需在上面sql的insert前面加上ignore关键字就行了。 |
如果我想对该表的多个字段进行去重呢?我们知道一个表加过多的索引是不好的一种行为,完全会印象数据的更新和插入,既然要批量插入,说明该表是会被频繁更新的。于是就有了
INSERT INTO test_ent(ent_name,creditcode,remark) SELECT '企业1','社会信用代码1','备注1' FROM dual WHERE NOT EXISTS(SELECT ent_name,creditcode,remark FROM table WHERE ent_name='企业1' and creditcode='社会信用代码1' and remark='备注1');
。那么如何把它改成批量呢?我现在唯一能想到的办法就是把多个插入sql放在同一个事物里面。1
2
3
4
5
6<insert id="batchInsert">
<foreach collection="entList" index="index" item="item"
separator=";">
INSERT INTO test_ent(ent_name,creditcode,remark) SELECT #{item.entName},#{item.creditcode},#{item.remark} FROM dual WHERE NOT EXISTS(SELECT ent_name,creditcode,remark FROM table WHERE ent_name=#{item.entName} and creditcode=#{item.creditcode} and remark=#{item.remark})
</foreach>
</insert>如果有更好的批量去重方式,欢迎提供。