#jpa
Вопрос:
Это таблица mysql.
create table Customer
(
id int auto_increment primary key,
birth date null,
createdTime time null,
updateTime datetime(6) null
);
Это мой java-код
@Before
public void init() {
this.entityManagerFactory=Persistence.createEntityManagerFactory("jpaLearn");
this.entityManager=this.entityManagerFactory.createEntityManager();
this.entityTransaction=this.entityManager.getTransaction();
this.entityTransaction.begin();
}
@Test
public void persistentTest() {
this.entityManager.setFlushMode(FlushModeType.COMMIT); //don't work.
for (int i = 0; i < 1000; i ) {
Customer customer = new Customer();
customer.setBirth(new Date());
customer.setCreatedTime(new Date());
customer.setUpdateTime(new Date());
this.entityManager.persist(customer);
}
}
@After
public void destroy(){
this.entityTransaction.commit();
this.entityManager.close();
this.entityManagerFactory.close();
}
Когда я читал вики-книги JPA, в них говорилось: «Это означает, что при вызове persist, слиянии или удалении базы данных ВСТАВКА, ОБНОВЛЕНИЕ, УДАЛЕНИЕ DML не выполняется до фиксации или до запуска сброса».
Но в то же время, когда мой код запускается, я читаю журнал mysql, я нахожу, что каждый раз при постоянном выполнении mysql будет выполнять sql. И я также читаю wireShark, каждый раз будет вызывать запрос к базе данных.
Я помню, что метод jpa saveAll может посылать инструкции SQL в базу данных пакетами? Если я хочу вставить 10000 записей, как повысить эффективность?
Ответ №1:
Мой ответ ниже предполагает, что вы используете Hibernate
в качестве реализации jpa. По умолчанию режим гибернации не включает пакетирование. Это означает, что он будет отправлять отдельную инструкцию SQL для каждой операции вставки/обновления.
Вы должны установить hibernate.jdbc.batch_size
свойству значение больше 0. Лучше установить это свойство в своем persistence.xml
файле, где у вас есть конфигурация jpa, но, поскольку вы не опубликовали его в вопросе, ниже оно задано непосредственно в EntityManagerFactory.
@Before
public void init() {
Properties properties = new Properties();
properties.put("hibernate.jdbc.batch_size", "5");
this.entityManagerFactory = Persistence.createEntityManagerFactory("jpaLearn", properties);
this.entityManager = this.entityManagerFactory.createEntityManager();
this.entityTransaction = this.entityManager.getTransaction();
this.entityTransaction.begin();
}
Затем, просматривая свои журналы, вы должны увидеть, что записи о клиентах сохраняются в базе данных партиями по 5 штук.
Для дальнейшего чтения, пожалуйста, проверьте: https://www.baeldung.com/jpa-hibernate-batch-insert-update
Комментарии:
1. Я нахожу эти штуки очень хитрыми. Если идентификатор сущности зависит от базы данных(mysql), то мы, возможно, не сможем сохранить пакетирование. Все мои сущности являются новыми объектами, и их идентификаторы зависят от mysql, потому что они являются автоинкрементами.
Ответ №2:
вы должны включить пакетную обработку для спящего режима
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_size=20
и использовать
reWriteBatchedInserts и rewriteBatchedStatements=верно
конец вашей строки подключения