jdbcTemplate.batchUpdate
是否在数据库服务器上执行多个单插入语句或 1个多值列表插入?
我知道它会立即将完整的查询有效负载发送到服务器,但不确定执行如何。
有人可以解释/帮助吗?
答案 0 :(得分:0)
来自问题:
jdbcTemplate.batchUpdate
是否在数据库服务器上执行多个单插入语句或 1个多值列表插入?
来自comment:
我对
感到好奇int[] org.springframework.jdbc.core.JdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes)
TL; DR: 它执行1个多值列表。
Spring Framework是开放源代码的,因此很容易查看源代码并发现实际上确实如此。
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个多值列表。
完整的答案是,它可能向数据库服务器发送一条SQL语句和一个多值列表,但是,如何实际执行批处理完全取决于JDBC驱动程序,这主要受以下方面的限制通信协议支持什么,因此唯一可以确定的方法是跟踪与服务器的通信。