基于springboot做一个上传Excel的功能。
前端插件用的是WebUploader。按配置来就行,略过。
后端保存Excel文件时,最开始采用的方式是,每一行读取的时候,就进行逻辑操作,这部分涉及数据库取值,写入。就是最简的Excel读入,数据量小的时候,比如,几十几百的时候,是没有问题的。但是,数据量破K的时候,操作数据库太频繁了。直接挂了,会出现超时问题。
后来选择采用,先将数据,写入一个set(这里是因为,在逻辑上,不想存入数据库的数据有重复的),然后对set进行批量操作。这时候采用了的是EntityManager的persist方法,插入的时候五百条刷一次,存一次。这个方法,减少了对数据库的操作,但是效率真的很差。上K的数据时间过长。
最后选择采用的方法是。PreparedStatement。也就是预编译对象。还是原生的jdbc操作比较靠谱。进行批量操作。写好集合后,进行addBatch。最后executeBatch。但是采用这个方法,需要注意一点,就是数据库连接的时候要开启批量管理,也就是这两个值需要设置useServerPrepStmts=false&rewriteBatchedStatements=true,不然速度还是偏慢。
具体代码可参考以下
@Override
public void batchInsert(List<MessageUser> list) throws SQLException {
DataSource ds = jdbcTemplate.getDataSource();
java.sql.Connection conn=ds.getConnection();
String insert_sqlString = "insert into t_message_user(sjhmOrNsrsbh,isread,messageId,sendType,sjhmOrNsrName,isSendOk)values(?,?,?,?,?,?)";
java.sql.PreparedStatement pstmt = conn
.prepareStatement(insert_sqlString);
for (int i = 0; i < list.size(); i++) {
pstmt.setString(1, list.get(i).getSjhmOrNsrsbh());
pstmt.setInt(2, 0);
pstmt.setLong(3, list.get(i).getMessageId());
pstmt.setString(4, list.get(i).getSendType() );
pstmt.setString(5, list.get(i).getSjhmOrNsrName());
pstmt.setInt(6, 1);
pstmt.addBatch();
/*entityManager.persist(list.get(i));
if (i % 500 == 0) {
entityManager.flush();
entityManager.clear();
}*/
}
pstmt.executeBatch();
}
其实在数据库操作这一块,很多时候原生jdbc真的会比后来封装的一些jpa好用一些,灵活性也更大。不过也有可能是我功夫不到家,没有领会jpa的精妙之处。
顺便,后来还有考虑过说读取cvs(因为电脑机子上的Excel版本是07的,原始的Excel只能读到6w+),但是cvs的格式是很不好处理的,Excel数据表还有一些格式要除去,比如表头之类的,cvs局限了这些。后来就采取了,数据先写在cvs文件里,然后用Excel打开,再复制进xls文件里就可以了,数据就不止6w+。