hibernate关系映射/加速批量插入
我有5个MySQL InnoDB表: Test,InputInvoice,InputLine,OutputInvoice,OutputLine
每个表都映射并在Hibernate中运行。 我玩过使用StatelessSession / Session和JDBC批量大小。 我删除了任何生成器类以让MySQL处理id生成 – 但它仍然执行速度很慢。 这些表中的每一个都在java类中表示,并相应地映射到hibernate中。 目前,当需要将数据写出来时,如果我使用StatelessSession,我会遍历对象并执行session.save(Object)
或session.insert(Object)
。 当我的行数达到最大jdbc批量大小(50)时,我也进行刷新和清除(当使用Session时)。
- 如果我在拥有对象并执行
session.save(master)
而不是每个对象的’parent’类中拥有它们会更快吗? - 如果我在主/容器类中使用它们,我如何在hibernate中映射它以反映关系? 容器类实际上不是它自己的表,而是一个基于两个索引run_id(int)和line(int)的关系。
- 另一个方向是:如何让Hibernate进行多行插入?
ID生成策略对于Hibernate中的批量插入至关重要。 特别是,IDENTITY生成通常不起作用(请注意,AUTO通常也会映射到IDENTITY)。 这是因为在批量插入期间,Hibernate有一个名为“requiresImmediateIdAccess”的标志,表示是否立即生成ID; 如果是,则禁用批处理。
您可以在DEBUG级别日志中轻松发现“立即执行标识插入” – 这意味着它已跳过批处理,因为它被告知插入后需要立即生成ID。
通常起作用的生成策略是TABLE和SEQUENCE,因为Hibernate可以预先生成ID,从而允许批量插入。
快速查看批量插入是否有效的方法是激活DEBUG级日志,因为BatchingBatcher将明确告诉您正在执行的批量大小(“执行批量大小:”+ batchSize)。
此外,以下属性对于实现批量插入很重要。 我不敢说他们是必需的,因为我不够Hibernate专家这么做 – 也许这只是我的特殊配置 – 但根据我的经验,他们仍然需要:
hibernate.order_inserts = true hibernate.order_updates = true
这些属性记录很差,但我相信他们所做的是使SQL INSERT和UPDATE语句能够正确分组以进行批处理执行; 我想这可能是你想要的多排插页。 如果我错了,请不要开枪,我记忆中的回忆。
我也会继续并假设您设置以下属性; 如果没有,这应该作为提醒:
hibernate.jdbc.batch_size = xx
其中xx是您所需的批量大小,当然。
对我来说,最后的解决方案是使用voetsjoeba的响应作为跳跃点。 我的hibernate配置使用以下选项:
hibernate.order_inserts = true hibernate.order_updates = true
-
我从使用
Session
变为StatelessSession
-
重新排序Java代码以一次处理批处理表中的所有元素。 所以表x,然后表y等等。
-
从每个class级中删除了
。 Java现在创建它并将其分配给对象 -
创建的逻辑允许我确定是否只是设置了一个id而不是将“空”行写入数据库
-
最后,我在他们的hibernate定义中为我的类启用了
dynamic-insert
,如下所示: