我需要将一个对象插入到具有多个嵌套对象的数据库中,例如:
class A{
List<B> b;
}
class B{
List<C> c;
List<D> d;
List<E> e;
}
现在我将有一个 A 的单个对象来持久化,该对象将有多个 B 类型的对象,而 B 又将有多个 C、D 和 E 类型的对象。
B、C、D、E 总共可能有 10,000 个对象。我已经使用 hibernate.cfg.xml 中的以下添加配置了批量插入
<property name="hibernate.jdbc.batch_size">50</property>
<property name="hibernate.order_inserts">true</property>
<property name="hibernate.order_updates">true</property>
<property name="hibernate.jdbc.batch_versioned_data">true</property>
我还添加了
rewriteBatchedStatements=true
在hibernate的connection.url属性中。
我正在为 ID 使用增量生成器。 我将收到 A 的 json 以及 B 的嵌套列表,并在每个 B 元素中依次嵌套 C、D 和 E。这将转换为对象 A 并使用
保存到数据库中session.save(A);
自从我启用了级联以来,所有嵌套对象都被持久化到数据库中。 10,000 个对象的总插入时间大约需要 25 秒。 我不确定是否启用了批处理,因为我看到像
这样的单个插入语句insert into C(id, val) values(1,"val");
insert into C(id, val) values(2,"val2");
我提到了 hibernate batch insert doc ,它要求我
session.flush();
session.clear();
在 jdbc 批量大小插入之后。我不确定在我的情况下该怎么做,我也尝试使用无状态 session ,但我也没有看到任何改进。任何有关如何提高性能的建议都会很棒。
最佳答案
我认为,如果您稍微改变一下方法,也许可以提高这里的性能。因此,您可以单独保存实体,而不是单个级联保存。这假设您声明了双向关系,我认为如果您希望执行此操作,您将需要该关系。
所以删除所有 List<T>
来自 A,然后单独保存 A。
类似于:
session.save(a)
session.evict(a)
这意味着 A 已被持久化,但不再存在于 session 中。然后,您可以单独保存关联的实体:
for (B b : a.getListOfB()) {
b.setA(a);
session.save(b);
}
如果您愿意,您可以刷新并逐出或使用无状态 session 。
关于java - Mysql 复杂对象 Hibernate 批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42787894/