我需要使用hibernate在数据库中插入大量数据,我正在查看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();
,但我看到flush不写数据到数据库上。阅读它,如果代码在事务中,那么在事务执行提交之前不会向数据库提交任何内容。
那么为什么需要使用flush/clear呢?似乎无用,如果数据不写入数据库,那么它们在内存中。
如何强制hibernate向数据库写入数据?
谢谢
数据被发送到数据库,并且不再在内存中。只是在事务提交之前,它不会被确定地持久化。这与在任何数据库工具中执行以下语句序列完全相同:
begin;
insert into ...
insert into ...
insert into ...
// here, three inserts have been done on the database. But they will only be made
// definitively persistent at commit time
...
commit;
flush包括执行insert语句。
提交包括执行提交语句。
数据将被写入数据库,但根据事务隔离级别,在事务提交之前,您将不会看到它们(在其他事务中)。
使用一些sql语句记录器,打印通过数据库连接传输的语句,然后您将看到这些语句被发送到数据库。
为了获得最佳性能,您还必须提交事务。刷新和清除会话清除hibernate缓存,但数据被移动到JDBC连接缓存,并且仍然未提交(不同的RDBMS/驱动程序显示不同的行为)-您只是将问题转移到其他地方,而没有真正的性能改进。
将flush()
放在提到的位置也可以节省内存,因为您的会话将定期清除。否则,您将在内存中拥有100000个对象,并且可能在更大的计数时耗尽内存。看看这篇文章。