Hibernate/MySQL批量插入问题

Mar*_*itt 5 java mysql orm hibernate

我无法让Hibernate在MySQL上执行批量插入.

我正在使用Hibernate 3.3和MySQL 5.1

从高层次来看,这就是正在发生的事情:

@Transactional
public Set<Long> doUpdate(Project project, IRepository externalSource) {
    List<IEntity> entities = externalSource.loadEntites();
    buildEntities(entities, project);
    persistEntities(project);
}
public void persistEntities(Project project) {
     projectDAO.update(project);
}
Run Code Online (Sandbox Code Playgroud)

这导致n个日志条目(每行1个),如下所示:

Hibernate:插入ProjectEntity(name,parent_id,path,project_id,state,type)值(?,?,?,?,?,?)

我希望看到这个被批处理,所以更新更高效.这个例程可能会导致生成数万行,并且每行数据包跳闸是一个杀手.

为什么不进行批量处理?(我的理解是,批处理插入在hibernate适当的地方应该是默认的).

Mat*_*nit 7

帕斯卡的答案是正确的.但是,因为您使用的是MySQL,所以我强烈建议您尝试rewriteBatchedStatements=true在JDBC URL中使用该参数.

此参数使JDBC驱动程序动态重写INSERT批处理以使用单个"多值"INSERT,例如:

INSERT INTO mytable (mycol) VALUES (0);
INSERT INTO mytable (mycol) VALUES (1);
INSERT INTO mytable (mycol) VALUES (2);
Run Code Online (Sandbox Code Playgroud)

将被重写为:

INSERT INTO mytable (mycol) VALUES (0), VALUES (1), VALUES (2);
Run Code Online (Sandbox Code Playgroud)

在某些情况下,这可能会产生显着差异.有关示例测量,请参见http://www.jroller.com/mmatthews/entry/speeding_up_batch_inserts_for.


Pas*_*ent 5

第13章中所述.批处理:

如果您正在进行批处理,则需要启用JDBC批处理.如果您想获得最佳性能,这绝对是必不可少的.将JDBC批处理大小设置为合理的数字(例如,10-50):

hibernate.jdbc.batch_size 20
Run Code Online (Sandbox Code Playgroud)

如果您使用身份标识符生成器,​​Hibernate会透明地禁用JDBC级别的插入批处理.

不要忘了flush,然后clear会话定期或者你会得到OutOfMemoryException在记录13.1.批量插入.

但IMO,对于数万行,您应该考虑使用StatelessSession接口.