博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jxl导入Excel 切割List 并使用MyBatis批量插入数据库
阅读量:6623 次
发布时间:2019-06-25

本文共 4989 字,大约阅读时间需要 16 分钟。

需求:从Excel导入大量客户数据。

项目环境:Spring+SpringMVC+MyBatis。

技术:使用jxl实现Excel数据导入。

方案:上传Excel文件,Controller层读取每行的内容保存到对象中,存储到List中。将保存数据的List每100个对象切割并存放到一个新的List 中的,然后使用一个大的List保存这些切割好的List组,传递到Service层遍历大List,将每组List传入的Dao层,让MyBatis批量插入数据。

废话不多说,上代码

Controller层

//获取用户上传的文件            Workbook workbook = Workbook.getWorkbook(file.getInputStream());            //获取工作簿sheet            Sheet sheet = workbook.getSheet(0);            //获取总行数            int rows = sheet.getRows();            //获取数据表中的数据            List
productList = new ArrayList<>(); Cell cell; for (int i = 1; i < rows; i++) { //该对象请放在循环内部,让GC进行回收,放在循环外面。List集合中的所有对象引用相同,保存的所有对象都是同一个引用 Product product = new Product(); //判断名称是否为空,如果为空结束遍历 if (StringUtil.isEmpty(sheet.getCell(0, i).getContents())) { break; } product.setId(sheet.getCell(0, i).getContents()); product.setContent(sheet.getCell(1, i).getContents()); //读取时间类型 cell = sheet.getCell(2, i); if (cell.getType() == CellType.DATE) { DateCell dc = (DateCell) cell; Date date = dc.getDate(); Calendar c = Calendar.getInstance(); c.setTime(date); //解析excel的时候会默认当前输入的时间为格林威治时间,需要转为当前时区的时间(之前8小时) c.add(Calendar.HOUR, -8); product.setSr_material_date(c.getTime()); } //读取时间类型 cell = sheet.getCell(3, i); if (cell.getType() == CellType.DATE) { DateCell dc = (DateCell) cell; Date date = dc.getDate(); Calendar c = Calendar.getInstance(); c.setTime(date); //解析excel的时候会默认当前输入的时间为格林威治时间,需要转为当前时区的时间(之前8小时) c.add(Calendar.HOUR, -8); product.setDate(c.getTime()); } product.setAddress(sheet.getCell(4, i).getContents()); product.setTel(sheet.getCell(5, i).getContents()); //将当前对象保存的productList中 productList.add(product); } //关闭资源 workbook.close(); //List切割 List
> dataList = new ArrayList<>(); int listSize = productList.size(); int toIndex = 100; int keyToken = 0; for (int i = 0; i < productList.size(); i += 100) { // 作用为toIndex最后没有100条数据则剩余几条newList中就装几条 if (i + 100 > listSize) { toIndex = listSize - i; } List
newList = productList.subList(i, i + toIndex); dataList.add(newList); } //将切割并打包好的List集合传递到Service层进行处理 productService.importFromExcel(dataList);复制代码

Service层

@Override    @Transactional    public int importFromExcel(List
> dataList) throws Exception { int result = 0; try { if (dataList != null) { for (List
list : dataList) { result += productMapper.batchInsertProduct(list); } } } catch (Exception e) { logger.error(e.getMessage()); throw e; } return result; }复制代码

MyBatis 批量插入

INSERT INTO t_product ( id, content, date, address, tel ) VALUES
(#{pd.id}, #{pd.content}, #{pd.date}, #{pd.address}, #{pd.tel})
复制代码

遇到的问题

刚开始想使用Lambda的partition进行List切割的,但是发现切割后返回的是List的父类Collection,看了下ArrayList源码,在将Collection转换为List操作是使用的遍历转换,先转换为对象数组。如果我这里要这么实现需要将切割后得到的Collection遍历转换为对象数组,再将对象数组中的多个元素中的多个对象转换出来,就会出现n*x的时间复杂度,并不是我需要的方式。就暂时使用上述的方法进行List切割。

ArrayList源码

/**     * Constructs a list containing the elements of the specified     * collection, in the order they are returned by the collection's     * iterator.     *     * @param c the collection whose elements are to be placed into this list     * @throws NullPointerException if the specified collection is null     */    public ArrayList(Collection
c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }复制代码

我写的Lambda切割List代码

List
> dataList = new ArrayList<>(); Collection
> partition = partition(productList, 100);复制代码

技术一般般,文章中有什么说的不对的地方,或者有更好的解决办法,还望多指教。谢谢。

转载地址:http://epxpo.baihongyu.com/

你可能感兴趣的文章
MYSQL企业常见架构与调优
查看>>
手机与PC音视频即时通讯
查看>>
手机音视频应用开发
查看>>
读Linux那些事儿之我是U盘笔记(八)
查看>>
RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V3.0 版本强势发布
查看>>
创建IOS应用程序通用下的Setting以及读取方式
查看>>
FreeBSD下一块网卡绑定多个IP
查看>>
无法在windows 2000 server安装sniffer pro的解决
查看>>
图解Oracle数据库(二)
查看>>
Slow shutdown of Windows 2003 Server after installing Exchange 2003 Server
查看>>
MySQL迁移到Cassandra技巧:放弃SQL思想
查看>>
多核分布式队列的实现:“偷”与“自私”的运用(4)
查看>>
Oracle to_char转数字小结
查看>>
MariaDB(mysql)之主从同步
查看>>
企业Windows域环境中的组策略应用案例二
查看>>
ASP.NET Aries 入门开发教程6:列表数据表格的格式化处理及行内编辑
查看>>
51CTO首届卡拉OK大赛:我唱,为欢聚而歌
查看>>
LVM逻辑卷管理详解
查看>>
如何实现 Service 伸缩?- 每天5分钟玩转 Docker 容器技术(97)
查看>>
java socket编程
查看>>