Session.Save отправляет запрос в базу данных? - PullRequest
0 голосов
/ 08 января 2019

Мне нужно улучшить производительность очень медленного кода, и я довольно новичок в 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

Этот алгоритм, конечно, проблематичен, когда в competitionToSave много competition с. Итак, мой план состоит в том, чтобы выбрать все competition s и winner s, наиболее задействованные в двух запросах к базе данных, данные предварительной обработки, что ускорит чтение, но, что более важно, чтобы я сохранял их с помощью insert / update партий по 100 competition с вместо сохранения их отдельно. Поскольку я довольно новичок в 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 Ответ

0 голосов
/ 08 января 2019

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

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

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

...