Session.Save отправляет запрос в базу данных?

Мне нужно улучшить производительность очень медленного кода, и я довольно новичок в Hibernate. Я тщательно изучил код и пришел к выводу, что проблема заключается в том, что он имеет большой набор сущностей для загрузки и update/insert, Чтобы перевести алгоритм в более понятный пример, скажем, у нас есть такой алгоритм:

for each competitionToSave in competitionsToSave
    competition <- load a Competition by competitionToSave from database

    winner <- load Person by competitionToSave.personID

    do some preprocessing

    if (newCompetition) then
        insert competition
    else
        update competition
    end if
end for

Этот алгоритм, конечно, проблематичен, когда есть много competitionв competitionToSave, Итак, мой план состоит в том, чтобы выбрать все competitionс и winnerбольше всего задействовано в двух запросах к базе данных - данные предварительной обработки, которые ускорят чтение, но, что более важно, гарантируют, что я сохраню через insert/update партии из 100 competitions вместо того, чтобы сохранять их отдельно. Поскольку я довольно новичок в Hibernate, я ознакомился с документацией и нашел следующий пример:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();

Однако я не уверен, что правильно понял. О методе .save() я прочитал:

Сохраните данный временный экземпляр, сначала назначив сгенерированный идентификатор. (Или используя текущее значение свойства идентификатора, если используется назначенный генератор.) Эта операция распространяется каскадно на связанные экземпляры, если сопоставление отображается с помощью cascade="save-update".

Но мне неясно, отправляется ли запрос в базу данных при каждом save, Я точен, если я предполагаю, что в примере, взятом из документации session.save(customer) сохраняет модификацию объекта в Session без отправки запроса в базу данных, а затем на каждый 20-й пункт session.flush() отправляет запрос в базу данных и session.clear() удаляет кеш Session?

1 ответ

Решение

Вы правы в своих предположениях, хотя вставки будут срабатывать один за другим:

insert into Customer(id , name) values (1, 'na1');
insert into Customer(id , name) values (2, 'na2');
insert into Customer(id , name) values (3, 'na3'); 

Вы можете попробовать воспользоваться функцией массовой вставки, чтобы еще больше повысить производительность.

Есть свойство hibernate, которое вы можете определить как одно из свойств hibernate. SessionFactory:

<property name="jdbc.batch_size">20</property>

С этой пакетной настройкой вы должны иметь такой вывод после каждого сброса:

insert into Customer(id , name) values (1, 'na1') , (2, 'na2') ,(3, 'na3')..

Одна вставка вместо двадцати.

Другие вопросы по тегам