【问题标题】:Mysql Complex Object Hibernate Batch insertMysql 复杂对象 Hibernate 批量插入
【发布时间】:2017-03-14 13:53:34
【问题描述】:

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

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 使用 increment 生成器。 我将收到 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 批量大小插入之后。我不确定在我的情况下该怎么做,我也尝试过使用无状态会话,我也没有看到任何改进。关于如何提高性能的任何建议都会很棒。

【问题讨论】:

    标签: java mysql hibernate batch-processing


    【解决方案1】:

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

    因此,从 A 中删除所有 List&lt;T&gt;,然后单独保存 A。

    类似:

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

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

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

    如果您愿意,您可以随后刷新和驱逐或使用无状态会话。

    【讨论】:

    • 确实帮不上忙,实际上慢了 2-3 秒
    • 您是否比较了每种情况下正在执行的 SQL?这可能会为比较方法提供一个更好的平台。
    猜你喜欢
    • 2011-01-19
    • 2011-02-15
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2015-07-03
    • 2011-07-04
    • 1970-01-01
    相关资源
    最近更新 更多