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

相關文章
相關標籤/搜索