需求:
导入Excel(上万条记录),每一行数据对应表(table_product)的一条记录。 导入时先读取Excel,并将数据insert到table_product表,同时insert到记录表,当barcode存在则做update操作。(barcode是Excel中的某一列的值)。
现有的处理方式很脑残:
[code="java"]
Action处理:
List list = new ArrayList();
Map map = excelReader.readExcelContent(is);
for (int i = 1; i <= map.size(); i++) {
list.add(map.get(i));
}
1、循环读取Excel,并将Excel的记录保存到一个ArrayList当中。
这一步的操作是否存在效率问题? ArrayList和Map是否合适?
service层处理方法:
for (int i = 0; i < list.size(); i++) {
String[] str = list.get(i);
// 查询数据是否存在
coll = findByBarCode(str[count]);
if (null != coll) {
//存在,做更新操作
update();
}else{
//不存在,做插入操作
insert();
drinsert(); //插入记录表
}
}
[/code]
这种方式很无脑,效率极低,求提出优化方案。
建一个临时表,先把所有的数据都用jdbc batch insert插入。再搞个store procedure 处理两个表就行了。在导入的时候作判断太花时间,没必要
如果要把excel导入共用,那么导入和业务逻辑可以分开,反之可以直接在导入中做业务。我看到你没有做历史数据的备份,如果是这样的话可以不用查询存在的数据,直接做一个删除操作再插入
数据源由excel提供,则默认数据是有限的,至少是一个excel文档能放下(人工生成的话几万条条了不起了),读取的性能靠POI的流读取足够保证
后边的插入/更新,做个独立线程,轮询接收队列(参考MQ)
excel读取生成数据->插入更新队列(生产端完工)
更新线程队列收到数据->执行插入/更新(更新端完工)
我之前也写过这样的程序, 思路跟我一样, 不过我用的是jdbc 批量操作的, 效率要高一些。1W跳记录挺快的, 不过跟你表数据大小和索引有关系。
写一个插入前触发器
判断是否存在,不存在增加并添加记录,存在就更新
程序从excel获取数据后,转换成sql语句
可以每500条用batch处理一次
我觉得吧,在你的Service层,可以把存在的 和不存在的分别存放在两个集合中,然后分别把这两个集合batch给数据库。