我想使用hibernate 批量更新,我尝试了批量插入,它运行正常,这是我用于休眠的配置 :
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.hbm2ddl.auto=update
hibernate.show_sql=false
hibernate.jdbc.fetch_size=100
hibernate.jdbc.batch_size=100
hibernate.jdbc.batch_versioned_data=true
hibernate.order_inserts=true
hibernate.order_updates=true
hibernate.cache.use_query_cache=false
hibernate.cache.use_second_level_cache=false
</value>
</property>
这是 DAO 代码:
public void updateBulkEmployees(List<Employee> employees) throws Exception {
for (int i = 0; i < employees.size(); i++) {
sessionFactory.getCurrentSession().update(employees.get(i));
if (i % 100 == 0) {
sessionFactory.getCurrentSession().flush();
sessionFactory.getCurrentSession().clear();
log.debug("Flushing batch:" + (int) (i / 100));
}
}
sessionFactory.getCurrentSession().flush();
sessionFactory.getCurrentSession().clear();
}
问题:我可以注意到方法执行需要花费很多时间(与不使用批处理完全相同),因此批量更新无法正常工作,我在配置中缺少某些内容或正在执行有问题 ? 请指教,谢谢。
答案 0 :(得分:1)
您如何知道批量插入有效?观察mysql.log是了解批量插入/更新是否有效的唯一方法(即使使用了批处理,Hibernate也始终记录单个查询)。
要在MySQL中使用批处理,必须在URL中设置特定的JDBC参数(Hibernate批处理使用JDBC批处理功能)。试试:
http://your_host:your_port/database?rewriteBatchedStatements=true
并且不要将GenerationType.AUTO或GenerationType.IDENTITY用作Id生成器。在这种情况下,Hibernate会禁用静默批处理功能。
提示:只需要中间刷新以避免OutOfMemory。 Hibernate尝试尽可能地查询数据库,因此如果您尝试更新1000000个实体,它会将所有实体保留在内存中直到提交。
答案 1 :(得分:0)
不应该是第二个“sessionFactory.getCurrentSession()。flush();”在循环之外?