JdbcTemplate的batchUpdate源码分析

    在以前的工做中遇到了须要执行屡次SQL的语句,因此查询了一下JdbcTemplate的batchUpdate方法的使用方法。java

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

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();
			}
		});

源码分析:数组

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

@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方法相似,就不一一举例。源码分析

相关文章
相关标签/搜索