使用jdbcTemplate.batchUpdate混淆进行批量插入

问题描述 投票:-1回答:1

jdbcTemplate.batchUpdate是否执行多个单插入语句OR在数据库服务器上插入1个多值列表?

我知道它会立即将完整的查询有效负载发送到服务器,但不确定执行如何。

有人可以解释/帮助吗?

java mysql jdbc spring-jdbc
1个回答
0
投票

来自问题:

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与服务器的通信。

© www.soinside.com 2019 - 2024. All rights reserved.