我需要使用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在数据库中写入数据?
由于
答案 0 :(得分:5)
数据 发送到数据库,不再存在于内存中。在事务提交之前,它并没有明确持久化。它与在任何数据库工具中执行以下语句序列完全相同:
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语句。
提交包括执行commit语句。
答案 1 :(得分:1)
数据将被写入数据库,但根据事务隔离级别,在事务提交之前,您将看不到它们(在其他事务中)。
使用一些sql语句记录器,它打印通过数据库连接传输的统计信息,然后您将看到统计信息被发送到数据库。
答案 2 :(得分:1)
为了获得最佳性能,您还必须提交交易。刷新和清除会话清除了休眠缓存,但是数据被移动到JDBC连接缓存,并且仍然是不公开的(不同的RDBMS /驱动程序显示不同的行为) - 您只是将问题转移到其他地方而没有真正改善性能。
答案 3 :(得分:1)
在所提到的位置flush()
可以保存您的记忆,因为您的会话将定期清除。否则,您将在内存中拥有100000个对象,并且可能会耗尽内存以进行更大的计数。查看this article。