java - Mysql 复杂对象 Hibernate 批量插入

标签 java mysql hibernate batch-processing

我需要将一个对象插入到具有多个嵌套对象的数据库中,例如:

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/

相关文章:

java - ResourceBundle [messages] 未找到 MessageSource : Can't find bundle for base name messages

java - 卡夫卡 : Publish message only if it doesn't already exist

mysql - php - 在搜索字段之前如何查看表格的一行

php - 大规模更新 MySQL 的最佳方法?

java - 懒惰 = false、急切和立即获取之间有什么区别?

java - 在android中打开SQLite数据库文件

java - 逆向文件java程序

MySQL 5.1 从 2 个表进行关系查询

java - JPQL - 在没有不必要的选择的情况下更新外键 ID

java - hibernate 错误 - QuerySyntaxException : users is not mapped [from users]