Как выполнять массовые вставки с помощью JpaRepository с динамическим batch_size, т. е. batch_size, неизвестно

#java #spring-boot #hibernate #jpa #spring-data-jpa

#java #весенняя загрузка #спящий режим #jpa #spring-data-jpa

Вопрос:

Я работаю в java spring boot API, где мне нужно вставить объемные данные в мою базу данных. Я знаю, как я мог этого добиться.

Чтобы получить массовую вставку с помощью Sring Boot и Spring Data JPA, вам нужны только две вещи:

  • установите параметр spring.jpa.properties.hibernate.jdbc.batch_size = 50
  • используйте saveAll() метод вашего репозитория со списком объектов, подготовленных для вставки.

Я хочу знать, как я могу достичь динамического размера пакета, т.Е. в некоторых классах мне нужно сохранить / вставить всего от 5 до 10 записей, в то время как в некоторых классах это число может составлять от 200 до 500 или более записей.

Теперь, как я мог бы добиться этого параметра dynamic batch_size.

Ответ №1:

Вы не можете динамически изменять batch_size только с помощью параметра EntityManager AP Ioption во время выполнения, но у вас может быть какой-то контроль:

1) Установите для batch_size наибольшее ожидаемое значение (т.е. 500)

2) Установите эти реквизиты, чтобы hibernate не пытался использовать ранее выполненные save/update инструкции.

 hibernate.order_inserts=true
hibernate.order_updatest=true
  

3) Используйте save вместо saveAll . Перебирайте свой список и сбрасывайте каждое количество раз, относящееся к сохраняемому классу:

 int = flushAfterThisNumber = 10;

for ( int i=0; i<entities.length; i   ) {
    session.save(entities[i]);
    if ( i % flushAfterThisNumber == 0 ) { 
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}
  

Обновить

Возможен обходной путь, но вам нужно создать пользовательский репозиторий, чтобы вы могли вводить EntityManager , затем разворачивать спящий Session режим, а затем иметь доступ к динамической настройке batch_size .

 public class CustomerRepositoryImpl implements CustomCustomerRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    public void saveAllInBatch(List<Ent> entities, int batchSize) {
        Session session = em.unwrap(Session.class);
        session.setJdbcBatchSize(batchSize);

        em.saveAll(entities);
    }
}
  

Комментарии:

1. Спасибо за ответ. Я использую SessionCreationPolicy. БЕЗ СОСТОЯНИЯ. Могу ли я по-прежнему использовать session.save или session. очистить / очистить.

2. если вы используете репозиторий JpaRepository, вы вызовете.. repo.flush()

3. Хорошо, я понимаю. Да, я должен использовать repo.save / repo.flush. Поскольку я расширяю свои репозитории из JpaRepository. Таким образом, динамической опции нет. Максимальный размер может составлять около 1000 прямо сейчас, и он может увеличиться в будущем.

4. Проверьте обновление. Но будьте осторожны, чтобы не злоупотреблять функцией разворачивания.

5. Что даст большую производительность, если сохранить с помощью цикла for или сохранить все с максимальным размером пакета.