Spring JdbcTemplate的batchUpdate中,没有看到conn.setAutoCommit(false)的操作

jdbcTemplate的batchupdate操作:

SpringJdbcTemplate的batch操作最后还是利用了JDBC提供的方法,Spring只是做了一下改造JDBC的batch操作:

final List<ExpressFreightBillImportDetail> tempOrderList = records;   
	       jdbcTemplate.batchUpdate(sql,new BatchPreparedStatementSetter() {  
	            @Override
	            public int getBatchSize() {  
	                 return tempOrderList.size();   
	            }
	            
	            @Override  
	            public void setValues(PreparedStatement ps, int i) throws SQLException {
	            	ps.setString(1, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getOrderNo()));
	            	ps.setInt(2, tempOrderList.get(i).getGoodNum());
	            	ps.setString(3, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getCollectPerson()));
	            	ps.setString(4, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getDeliveryPerson()));
	            	ps.setBigDecimal(5, tempOrderList.get(i).getSumFee());
	            	ps.setBigDecimal(6, tempOrderList.get(i).getDeliveryFee());
	            	ps.setBigDecimal(7, tempOrderList.get(i).getPackageFee());
	            	ps.setBigDecimal(8, tempOrderList.get(i).getInsuredFee());
	            	ps.setBigDecimal(9, tempOrderList.get(i).getCod());
	            	ps.setLong(10, StringUtil.nullConvertToLong(tempOrderList.get(i).getDeliveryBranchId()));
	            	ps.setString(11, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getDeliveryBranch()));
	            	ps.setLong(12, tempOrderList.get(i).getBillId());
	            	ps.setString(13, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getBillNo()));
	            	ps.setInt(14, tempOrderList.get(i).getEffectFlag());
	            	ps.setString(15, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getDismatchReason()));
	            	ps.setLong(16, StringUtil.nullConvertToLong(tempOrderList.get(i).getImportPersonId()));
	            	ps.setString(17, StringUtil.nullConvertToEmptyString(tempOrderList.get(i).getImportPerson()));
	            	ps.setDate(18, new java.sql.Date(tempOrderList.get(i).getImportTime().getTime()));
	            }   
	      });   
为什么在Spring JdbcTemplate的batchUpdate中,没有看到conn.setAutoCommit(false)的操作? 
这是因为Spring有它自己的事务管理机制 
如果你配置了JDBC的事务管理,那么DataSourceTransactionManager会自动设置 

DataSourceTransactionManagerr的doBegin方法。

下面我们可以看下:spring中的源码:

public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
		if (logger.isDebugEnabled()) {
			logger.debug("Executing SQL batch update [" + sql + "]");
		}

		return execute(sql, new PreparedStatementCallback<int[]>() {
			public int[] doInPreparedStatement(PreparedStatement ps) throws SQLException {
				try {
					int batchSize = pss.getBatchSize();
					InterruptibleBatchPreparedStatementSetter ipss =
							(pss instanceof InterruptibleBatchPreparedStatementSetter ?
							(InterruptibleBatchPreparedStatementSetter) pss : null);
					if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
						for (int i = 0; i < batchSize; i++) {
							pss.setValues(ps, i);
							if (ipss != null && ipss.isBatchExhausted(i)) {
								break;
							}
							ps.addBatch();
						}
						return ps.executeBatch();
					}
					else {
						List<Integer> rowsAffected = new ArrayList<Integer>();
						for (int i = 0; i < batchSize; i++) {
							pss.setValues(ps, i);
							if (ipss != null && ipss.isBatchExhausted(i)) {
								break;
							}
							rowsAffected.add(ps.executeUpdate());
						}
						int[] rowsAffectedArray = new int[rowsAffected.size()];
						for (int i = 0; i < rowsAffectedArray.length; i++) {
							rowsAffectedArray[i] = rowsAffected.get(i);
						}
						return rowsAffectedArray;
					}
				}
				finally {
					if (pss instanceof ParameterDisposer) {
						((ParameterDisposer) pss).cleanupParameters();
					}
				}
			}
		});
	}
其中对批量操作还进行了判断,如果可以则执行批量操作,否则一条一条的插入记录。

将excel数据导入数据库的程序时,由于数据量大,准备采用jdbc的批量插入。于是用了preparedStatement.addBatch();当加入1w条数据时,再执行插入操作,preparedStatement.executeBatch()。原以为这样会很快,结果插入65536条数据一共花30多分钟,完全出乎我的意料。网上百度了一下在处理这种大批量数据导入的时候是如何处理的,发现大部分都是用的jdbc批量插入处理,但不同的是:他们使用了con.setAutoCommit(false);然后再preparedStatement.executeBatch()之后,再执行con.commit();网上摘了一段说明:

* When importing data into InnoDB, make sure that MySQL does not have autocommit mode enabled because that

      requires a log flush to disk for every insert. To disable autocommit during your import operation, surround it with

      SET autocommit and COMMIT statements:

      SET autocommit=0;
     ... SQL import statements ...
     COMMIT;



Spring JdbcTemplateSpring框架的一个重要组件,它为开发者提供了一个简单方便、易于扩展的JDBC操作方式。JdbcTemplate提供了许多有用的方法,其之一就是 batchUpdate()。它实现了批量更新操作,可以显著提高数据库操作效率。 batchUpdate()方法用于执行批量更新操作,可以一次性执行多条SQL语句,同时返回每条SQL语句的更新数量,这在大数据量插入或更新时格外有用。开发者只需要将所有的SQL语句存储在一个字符串数组,然后将该数组传递给batchUpdate()方法即可。batchUpdate()方法会返回一个int类型的数组,其每个元素表示相应的SQL语句所更新的记录数。 例如,以下代码展示了如何使用batchUpdate()方法: ```java String[] sqls = {"INSERT INTO user(name, age) VALUES ('Tom', 28)", "UPDATE user SET age = 29 WHERE name = 'Tom'", "DELETE FROM user WHERE name = 'Tom'"}; int[] counts = jdbcTemplate.batchUpdate(sqls); ``` 上述代码,我们将三个SQL语句存储在一个字符串数组sqls,然后使用jdbcTemplate.batchUpdate(sqls)执行批量更新操作。最后,我们将每个SQL语句更新的记录数存储在一个int数组counts。 总之,Spring JdbcTemplatebatchUpdate()方法是一个高效的数据库操作方法,可以为开发者提供更快速、更可靠的JDBC操作方式。同时,它还具有批处理的优点,可以大大节省数据库操作的时间和资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值