![](/img/trans.png)
[英]batch processing with dynamic insert query using spring “jdbcTemplate.batchUpdate”
[英]Batch insert using jdbcTemplate.batchUpdate confusion
jdbcTemplate.batchUpdate
是否在數據庫服務器上執行多個單插入語句或1 個多值列表插入?
我知道它會立即將完整的查詢有效負載發送到服務器,但不確定執行是如何發生的。
有人可以解釋/幫助嗎?
從問題:
jdbcTemplate.batchUpdate
是否在數據庫服務器上執行多個單插入語句或1 個多值列表插入?
來自評論:
我很好奇
int[] org.springframework.jdbc.core.JdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes)
TL;DR:它執行 1 個多值列表。
Spring 框架是開源的,所以很容易查看源代碼並看到它確實如此。
batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes)
@Override
public int[] batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes) throws DataAccessException {
if (batchArgs.isEmpty()) {
return new int[0];
}
return batchUpdate(
sql,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Object[] values = batchArgs.get(i);
int colIndex = 0;
for (Object value : values) {
colIndex++;
if (value instanceof SqlParameterValue) {
SqlParameterValue paramValue = (SqlParameterValue) value;
StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue());
}
else {
int colType;
if (argTypes.length < colIndex) {
colType = SqlTypeValue.TYPE_UNKNOWN;
}
else {
colType = argTypes[colIndex - 1];
}
StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value);
}
}
}
@Override
public int getBatchSize() {
return batchArgs.size();
}
});
}
可以看出,它調用了以下方法。
batchUpdate(String sql, final BatchPreparedStatementSetter pss)
@Override
public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL batch update [" + sql + "]");
}
int[] result = execute(sql, (PreparedStatementCallback<int[]>) ps -> {
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<>();
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();
}
}
});
Assert.state(result != null, "No result array");
return result;
}
可以看出,它創建了一個PreparedStatement
,進入一個調用addBatch()
的循環,最后調用executeBatch()
。
所以,簡短的回答是: 1 multi-valued list 。
完整的答案是它可能會向數據庫服務器發送一個 SQL 語句和一個多值列表,但是它完全取決於 JDBC 驅動程序如何實際實現批處理,主要受通信協議支持的限制,所以唯一的方法確定是跟蹤與服務器的通信。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.