JdbcTemplate的batchUpdate源码分析

本文探讨了在Java开发中如何使用JdbcTemplate的batchUpdate方法进行批量数据库操作,特别是批处理插入和更新。重点讲解了BatchPreparedStatementSetter接口的setValues和getBatchSize方法的用法,并对源码进行了简单分析。虽然分析可能存在不足,但提供了理解JdbcTemplate批量操作的基本思路。

    在之前的工作中遇到了需要执行多次SQL的语句,所以查询了一下JdbcTemplate的batchUpdate方法的使用方法。

    batchUpdate(String,BatchPreparedStatementSetter方法主要是插入,更新时使用。该方法中的BatchPreparedStatementSetter类需要重写setValues方法(执行一条语句时,进行参数的插入),getBatchSize方法(获取需要插入的数组)

		List<Object> o = new ArrayList<Object>();
		int[] i = jdbcTemplate.batchUpdate(sql,new BatchPreparedStatementSetter() {
			@Override
			public void setValues(PreparedStatement ps, int i) throws SQLException{
				Teacher t = teachers.get(i);
				ps.setLong(1, t.getId());
			}
			
			@Override
			public int getBatchSize() {
				return teachers.size();
			}
		});

源码分析:

        由于本人比较菜鸡,有一些点分析的不到位,请见谅,欢迎指出。

	@Override
	public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
		//判断是否为Debug模式
		if (logger.isDebugEnabled()) {
			//输出SQL语句
			logger.debug("Executing SQL batch update [" + sql + "]");
		}
		//->为JDk8的新特性,Lambda表达式。执行sql语句。
		int[] result = execute(sql, (PreparedStatementCallback<int[]>) ps -> {
			try {
				//获取参数数组大小
				int batchSize = pss.getBatchSize();
				InterruptibleBatchPreparedStatementSetter ipss =
						(pss instanceof InterruptibleBatchPreparedStatementSetter ?
						(InterruptibleBatchPreparedStatementSetter) pss : null);
				//确定Jdbc的驱动是否支持批处理
				if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
					for (int i = 0; i < batchSize; i++) {
						pss.setValues(ps, i);
						//isBatchExhausted方法判断批处理是否完成
						if (ipss != null && ipss.isBatchExhausted(i)) {
							break;
						}
						//向PreparedStatementCallback类中添加执行代码
						ps.addBatch();
					}
					//执行插入代码代码
					return ps.executeBatch();
				}
				else {
					//若是驱动不支持,则设置一个Integer列表,用于返回参数
					List<Integer> rowsAffected = new ArrayList<>();
					for (int i = 0; i < batchSize; i++) {
						pss.setValues(ps, i);
						if (ipss != null && ipss.isBatchExhausted(i)) {
							break;
						}
						//执行更新后,向列表中添加放回值
						rowsAffected.add(ps.executeUpdate());
					}
					//将列表转为数组??,有点意思。不用toArray方法
					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();
				}
			}
		});

		Assert.state(result != null, "No result array");
		return result;
	}

    其他的batch方法类似,就不一一举例。

转载于:https://my.oschina.net/u/4109273/blog/3033797

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值