https://www.tutorialspoint.com/hibernate/hibernate_batch_processing.htm
ользую Hibernate ORM и PostgreSQL в своем приложении, а иногда я использую пакетные операции. И сначала я не понял, почему в журналах с размером пакета = 25 генерируется 25 запросов, и сначала подумал, что он работает неправильно. Но после этого я посмотрел на исходный код драйвера pg и обнаружил следующие строки в классе PgStatement:
public int[] executeBatch() throws SQLException {
this.checkClosed();
this.closeForNextExecution();
if (this.batchStatements != null && !this.batchStatements.isEmpty()) {
this.transformQueriesAndParameters();
//confuses next line, because we have array of identical queries
Query[] queries = (Query[])this.batchStatements.toArray(new Query[0]);
ParameterList[] parameterLists =
(ParameterList[])this.batchParameters.toArray(new ParameterList[0]);
this.batchStatements.clear();
this.batchParameters.clear();
и в классе PgPreparedStatement
public void addBatch() throws SQLException {
checkClosed();
if (batchStatements == null) {
batchStatements = new ArrayList<Query>();
batchParameters = new ArrayList<ParameterList>();
}
batchParameters.add(preparedParameters.copy());
Query query = preparedQuery.query;
//confuses next line
if (!(query instanceof BatchedQuery) || batchStatements.isEmpty()) {
batchStatements.add(query);
}
}
Я заметил, что получается, что если размер пакета составляет 25, то отправляется 25 запросов с прикрепленными к ним параметрами.
Журналы базы данных подтверждают это, например:
2017-12-06 01:22:08.023 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ: выполнение S_3: BEGIN
2017-12-06 01:22:08.024 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ: выполнение S_4: select nextval ('tests_id_seq')
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ: выполнение S_2: insert into tests (name, id) values ($1, $2)
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory ПОДРОБНОСТИ: параметры: $1 = 'test', $2 = '1'
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ: выполнение S_2: insert into tests (name, id) values ($1, $2)
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory ПОДРОБНОСТИ: параметры: $1 = 'test', $2 = '2'
...
x23 queries with parameters
...
2017-12-06 01:22:08.063 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ: выполнение S_5: COMMIT
Но я думал, что один запрос должен быть выполнен с массивом из 25 параметров. Или я не понимаю, как пакетные вставки работают с подготовленным оператором? Зачем дублировать один запрос n раз?
В конце концов, я пытался отлаживать свои запросы на этом месте
if (!(query instanceof BatchedQuery) || batchStatements.isEmpty()) {
и заметил, что мои запросы всегда являются экземпляром SimpleQuery, а не BatchedQuery. Может быть, это решение проблемы? Информация о BatchedQuery я не смог найти