以下是批量插入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可以完成这项工作。
优化查询的最佳方法是什么?感谢。
答案 0 :(得分:1)
正如SO question identity
中所回答的那样,对于批处理确实不起作用。对于MySQL,您最终会在应用程序中生成ID(例如,使用生成器assigned
或uuid
- 特定于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上的参数含义的描述。