Mysql复杂对象Hibernate批量插入

时间:2017-03-14 13:53:35

标签: 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类型的对象。

可能总共有10,000个B,C,D和E对象组合在一起。我使用以下对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使用增量生成器。 我会在每个B元素中收到一个A的json以及嵌套的B列表和嵌套的C,D和E.这将转换为对象A并使用

保存到db中
session.save(A);

因为我启用了级联,所有嵌套对象都会持久存储到db中。 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批量大小插入后。我不知道如何在我的情况下这样做,我也尝试使用无状态会话,我也没有看到任何改进。关于如何改善性能的任何建议都会很棒。

1 个答案:

答案 0 :(得分:0)

如果您稍微改变一下方法,我认为您可以在这里提高性能。因此,您可以单独保存实体,而不是单个级联保存。这假设您已声明了双向关系,如果您希望这样做,我认为您需要这些关系。

因此,从A中删除所有List<T>,然后单独保存A.

类似的东西:

session.save(a)
session.evict(a)

这意味着A已被持久化但在会话中不再存在。然后,您可以单独保存关联的实体:

for (B b : a.getListOfB()) {
  b.setA(a);
  session.save(b);
}

如果您愿意,可以刷新并逐出或使用无状态会话。