jdbcTemplate.batchUpdate
是否执行多个单插入语句OR在数据库服务器上插入1个多值列表?
我知道它会立即将完整的查询有效负载发送到服务器,但不确定执行如何。
有人可以解释/帮助吗?
来自问题:
jdbcTemplate.batchUpdate
是否执行多个单插入语句OR在数据库服务器上插入1个多值列表?
来自comment:
我对
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)
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)
可以看出,它创建了一个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
。
所以,简短的答案是:1个多值列表。
完整的答案是,它[[很可能向数据库服务器发送一条SQL语句和一个多值列表,但是,JDBC驱动程序如何真正实现批处理完全取决于JDBC驱动程序,这主要受通信协议的限制支持,因此唯一可以确定的方法是trace与服务器的通信。