简体   繁体   中英

Batch insert using jdbcTemplate.batchUpdate confusion

Does jdbcTemplate.batchUpdate execute multiple single insert statements OR 1 multi value list insert on the database server?

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?

From comment :

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

TL;DR: It executes 1 multi-valued list.


Spring Framework is open-source, so it's easy to look at the source code and see that is actually does.

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() .

So, the short answer is: 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM