SpringBoot+MyBatis+Oracle之处理上传文件中数据的批量存储

1.前言

       本文为开发过程中记录过程优化的文章,记录一下方便勤于查看,也欢迎各位朋友提出建议。文笔方面不好,大家别介意~~

2.背景介绍

       首先,先简单介绍一下这块功能的业务吧。平台使用者可以通过平台的场景能力新建一个场景,然后将这批用户通过txt文件进行上传操作,然后平台底层会根据使用者配置的侧重点对上传的这批用户进行行为追踪等最后汇总为分析报告提供给使用者进行查看和下载功能。

3.遇到问题

       上传文件处理这部分,同事刚开始的时候使用的是解析文件后逐条执行Oracle的insert操作,刚开始少量用户测试的时候没有发现这里的问题,但是逐渐加大用户量后发现执行时间越来越长,然后就开始debug跟踪查找问题。发现解析文件这里的逻辑是解析出来一条数据后调用Mapper实例执行一次insert语句,然后再去解析文件的下一条信息,这样的操作逻辑直到文件数据解析完毕。这样的逻辑处理方式太影响后台的处理效率,进而影响到整个业务流程的处理效率,会影响使用者使用平台的积极性。因此,我就临时接手了这部分功能的优化工作,开始准备将这里更改成批量处理的方式。

       由于之前了解这块的整个业务流程,所以临时接手后没有浪费多余的时间去了解业务流程,在梳理业务这部分节省了时间。对于这部分我修改后的处理逻辑分为两步执行:

           1.解析文件内的用户信息后,将信息保存到List集合中(这部分需要进行一些数据合法性校验等操作);
           2.将保存用户信息的List集合进行批量入库的操作;

       接下来开始上代码实现~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4.代码走起

       1.解析文件内的用户信息后,将信息保存到List集合中(这部分需要进行一些数据合法性校验等操作);

if(file != null && !file.isEmpty()){
	logger.info("用户上传的文件存在,且不为空......................");
	//获取客户群文件内容
	BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(),"UTF-8"));

	String line;
	while ((line = reader.readLine()) != null) {
		//RegexUtil.isLegitimacyInfo方法中封装了对输入数据的合法性验证比对
		if(line !=null && !"".equals(line) && RegexUtil.isLegitimacyInfo(line)){
			list.add(line);
		}
	}
}

       2.将保存用户信息的List集合进行批量入库的操作(这部分是重点,优化后节省了大部分操作时间,提高了整体操作效率);

/**
 * 批量将list中保存的数据插入到指定的数据表中
 * @param list 批量执行插入操作的数据集合
 * @param tableName 数据执行插入操作的数据表名称
 */
public int batchImportData(List<String> list, String tableName) {
	int result = 0;
	SqlSession batchSqlSession = null;

	try {
		int batchCount = 1000;//每批执行commit操作的数据条数
		int batchLastIndex = batchCount;//每批批量操作的最后一条数据在list中存储的下标值

		batchSqlSession = this.sqlSessionTemplate
				.getSqlSessionFactory()
				.openSession(ExecutorType.BATCH, false);// 获取批量方式的sqlsession
		//通过新的session获取mapper
		DataMapper mapper = batchSqlSession.getMapper(DataMapper.class);

		for (int index = 0; index < list.size();) {
			if (batchLastIndex >= list.size()) {
				batchLastIndex = list.size();

				result = result + mapper.batchImportData(list.subList(index, batchLastIndex), tableName);
				batchSqlSession.commit();
				//清理缓存,防止溢出
				batchSqlSession.clearCache();
				System.out.println("index:" + index+ " batchLastIndex:" + batchLastIndex);
				break;// 数据插入完毕,退出循环
			} else {
				result = result + mapper.batchImportData(list.subList(index, batchLastIndex), tableName);
				batchSqlSession.commit();
				//清理缓存,防止溢出
				batchSqlSession.clearCache();
				System.out.println("index:" + index+ " batchLastIndex:" + batchLastIndex);
				index = batchLastIndex;// 设置下一批下标
				batchLastIndex = index +(batchCount-1);
			}
		}
		batchSqlSession.commit();
	} catch(Exception e) {
		result = 0;
		logger.info("执行批量保存过程中出错,具体信息请查看日志!");
		e.printStackTrace();
	} finally {
		batchSqlSession.close();
	}

	return result;
}

       通过上述的优化方式后,整个业务流程的执行效率得到大大的提升。但是上述代码存在一个小问题:就是批量处理执行完毕之后,该方法的返回值result的结果值不对,各位朋友如果需要借鉴的话这个返回值的部分可以调整一下。

       对于这个result的返回值问题,我目前的思路是将这个值作为参数传递进来,然后每一次执行完毕之后进行累加操作,最后在整个方法执行完毕后将这个最终的累加结果值返回给方法的调用者进行使用。
当然,如果有其他更好的处理思路欢迎各位朋友留言,不胜感激!!!!!

5.总结

       好了,以上就是本篇文章的全部内容了。亲爱的读者朋友,非常感谢你能看到这里。如果觉得本篇文章写的还可以不要忘了留下你的痕迹,谢谢。原创不易,内容均纯手打,希望大家多多支持,❤️ 不要忘记留下你学习的脚印 [点赞 + 收藏 + 评论]

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值