休眠 - 慢速批量插入

时间:2015-04-24 15:01:30

标签: java mysql hibernate

以下是批量插入MySQL远程数据库的代码。

    Session session = db.setSession();
    Transaction tx = session.beginTransaction();

    for ( int i=0; i<e.getContents().size(); i++ ) {
        Content content = e.getContents().get(i);
        session.save(content);
        if ( i % 40 == 0 ) { 
            session.flush();
            session.clear();
        }
    }
    tx.commit();

映射的定义方式如下:

class name="Database.Content" table="..." schema="" catalog="...">
    <id name="id">
        <column name="id" sql-type="int" not-null="true"/>
        <generator class="identity"/>
    </id>
    <property name="week">
        <column name="week" sql-type="int"/>
    </property>
    <property name="type">
        <column name="type" sql-type="int" not-null="true"/>
    </property>
    <many-to-one name="group" class="Database.Group">
        <column name="`group`"/>
    </many-to-one>
    <many-to-one name="table" class="Database.Table">
        <column name="`table`" not-null="true"/>
    </many-to-one>
</class>

我还在hibernate.cfg.xml中设置了一些属性:

<property name="hibernate.jdbc.batch_size">40</property>
<property name="hibernate.cache.use_second_level_cache">false</property>

不幸的是,插入150行需要大约30秒,这非常慢。我已经读过设置generator=identity可能会完全禁用批量插入。但是,如果我删除generator行,我最终会收到Duplicate key错误。我想知道我是否可以发送null作为我的id,因此MySQL可以完成这项工作。

优化查询的最佳方法是什么?感谢。

1 个答案:

答案 0 :(得分:1)

正如SO question identity中所回答的那样,对于批处理确实不起作用。对于MySQL,您最终会在应用程序中生成ID(例如,使用生成器assigneduuid - 特定于Hibernate)或使用符合JPA的table生成器。

使用表生成器的示例:

<table-generator name="EMP_GEN"
        table="GENERATOR_TABLE"
        pk-column-name="key"
        value-column-name="hi"
        pk-column-value="EMP"
        allocation-size="20"/>

详见http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#mapping-declaration-id。还有Java EE page上的参数含义的描述。

相关问题