Hibernate 属性 hibernate.jdbc.batch_size 是 hibernate 优化插入或更新语句的一种方式,而刷新循环是关于内存耗尽的。
当您尝试保存实体 hibernate fire 1 insert 语句时没有批量大小,因此如果您使用大集合,则对于每个 save hibernate fire 1 语句
想象一下下面这段代码:
for(Entity e : entities){
session.save(e);
}
这里 hibernate 将在您的集合中为每个实体触发 1 个插入语句。如果您的集合中有 100 个元素,那么将触发 100 个插入语句。
这种方法效率不高主要有两个原因:
- 1) 您的一级缓存呈指数级增长,您可能很快就会收到
OutOfMemoryException。
- 2) 由于每个语句的网络往返,您会降低性能。
hibernate.jdbc.batch_size 和刷新循环有 2 个不同的目的,但是是互补的。
Hibernate 使用第一个来控制批处理的实体数量。在 Hibernate 中使用 java.sql.Statement.addBatch(...) 和 executeBatch() 方法。
所以 hibernate.jdbc.batch_size 告诉 hibernate 在调用 executeBatch() 之前它必须调用多少次 addBatch()。
所以设置这个属性并不会阻止你的内存耗尽。
为了处理内存,您必须定期刷新会话,这就是刷新循环的目的。
当你写的时候:
for(Entity e : entities){
if (i % 100 == 0 && i>0) {
session.flush();
session.clear();
}
}
您是在告诉 hibernate 每 100 个实体刷新和清除会话(释放内存)。
那么现在两者之间的联系是什么?
为了达到最佳效果,您必须定义您的 jdbc.batch_size 和您的刷新参数相同。
如果您定义的刷新参数低于您选择的 batch_size,那么休眠将更频繁地刷新会话,因此它将创建小批量,直到达到 btach 大小
效率不高
当 2 个相同时,如果集合的大小不是 batch_size 的倍数,则休眠将只执行最佳大小的批次,最后一个除外。
您可以查看以下post 了解有关最后一点的更多详细信息