Hibernate / MySQL批量插入问题

时间:2010-02-20 18:21:39

标签: java mysql hibernate orm

我无法让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);
}

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

  

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

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

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

3 个答案:

答案 0 :(得分:7)

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

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

INSERT INTO mytable (mycol) VALUES (0);
INSERT INTO mytable (mycol) VALUES (1);
INSERT INTO mytable (mycol) VALUES (2);

将重写为:

INSERT INTO mytable (mycol) VALUES (0), VALUES (1), VALUES (2);

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

答案 1 :(得分:5)

Chapter 13. Batch processing中所述:

  

如果您正在进行批量处理   处理你需要启用   使用JDBC批处理。这是   如果你愿意,绝对必要   实现最佳性能。设置   JDBC批量大小合理的数量   (例如10-50):

hibernate.jdbc.batch_size 20
     

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

不要忘记定期flush然后clear会话,否则13.1. Batch inserts中会记录OutOfMemoryException

但IMO,对于数万行,您应该考虑使用the StatelessSession interface

答案 2 :(得分:0)

Pascal几乎已经在hibernate上下文中钉了它。作为替代方案,您可以使用jbdc模板的Batchsqlupdate。但是我必须警告你,hibernate缓存的实例可能无法反映使用上面所做的更改。在我们的项目中,我们必须采取预防措施来克服这个问题,制定一个不同的时间表(创建另一个问题,但在我们的控制范围内)