简体   繁体   English

批量插入使用 jdbcTemplate.batchUpdate 混淆

[英]Batch insert using jdbcTemplate.batchUpdate confusion

Does jdbcTemplate.batchUpdate execute multiple single insert statements OR 1 multi value list insert on the database server? jdbcTemplate.batchUpdate是否在数据库服务器上执行多个单插入语句1 个多值列表插入?

I know that it sends the complete query payload at once to the server but am not sure how the execution takes place.我知道它会立即将完整的查询有效负载发送到服务器,但不确定执行是如何发生的。

Can someone please explain/help?有人可以解释/帮助吗?

From question:从问题:

Does jdbcTemplate.batchUpdate execute multiple single insert statements OR 1 multi value list insert on the database server? jdbcTemplate.batchUpdate是否在数据库服务器上执行多个单插入语句1 个多值列表插入?

From comment :来自评论

I was curious about int[] org.springframework.jdbc.core.JdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes)我很好奇int[] org.springframework.jdbc.core.JdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes)

TL;DR: It executes 1 multi-valued list. TL;DR:它执行 1 个多值列表。


Spring Framework is open-source, so it's easy to look at the source code and see that is actually does. 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();
                }
            });
}

As can be seen, it calls the following method.可以看出,它调用了以下方法。

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;
}

As can be seen, it creates a single PreparedStatement , enters a loop calling addBatch() , and finally calls executeBatch() .可以看出,它创建了一个PreparedStatement ,进入一个调用addBatch()的循环,最后调用executeBatch()

So, the short answer is: 1 multi-valued list .所以,简短的回答是: 1 multi-valued list

The full answer is that it likely sends one SQL statement and a multi-valued list to the database server, however it is entirely up to the JDBC driver how it actually implements batching, mostly limited by what the communication protocol supports, so the only way to know for sure is to trace the communication with the server.完整的答案是它可能会向数据库服务器发送一个 SQL 语句和一个多值列表,但是它完全取决于 JDBC 驱动程序如何实际实现批处理,主要受通信协议支持的限制,所以唯一的方法确定是跟踪与服务器的通信。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用spring“ jdbcTemplate.batchUpdate”进行动态插入查询的批处理 - batch processing with dynamic insert query using spring “jdbcTemplate.batchUpdate” jdbcTemplate.batchUpdate 跳过策略 - jdbcTemplate.batchUpdate Skip policy jdbctemplate.batchupdate 是多线程的还是并发的? - Is jdbctemplate.batchupdate multithreaded or concurrent? JdbcTemplate.batchUpdate() 在一项插入错误时返回 0,但将剩余项插入 sql 服务器数据库,尽管使用 @Transactional - JdbcTemplate.batchUpdate() returns 0, on insert error for one item but inserts the remaining item into sql server db despite using @Transactional 为 jdbcTemplate.batchUpdate() 方法编写单元测试 - Write unit test for jdbcTemplate.batchUpdate() method 有关大量查询的jdbcTemplate.batchUpdate()问题 - Issue with jdbcTemplate.batchUpdate() for large list of queries 列表小于 getBatchSize() 的 jdbcTemplate.batchUpdate() 抛出 IndexOutOfBoundsException 错误 - jdbcTemplate.batchUpdate() with smaller list than getBatchSize() throws IndexOutOfBoundsException error 为什么 Spring 的 jdbcTemplate.batchUpdate() 这么慢? - Why Spring's jdbcTemplate.batchUpdate() so slow? 如何包括jdbctemplate.batchUpdate(String sql,List的两个参数 <Object[]> batchArgs)? - How to include two parameters for jdbctemplate.batchUpdate(String sql, List<Object[]> batchArgs)? 有什么更好的方法检查JdbcTemplate.batchUpdate中的名称字段,名称表的SQL注入? - What better way to check SQL injection of names field, names tables in JdbcTemplate.batchUpdate?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM