我正在使用Spring HibernateTemplate,需要每秒将数百条记录插入到mysql数据库中。
不确定最有效的方法是什么,但我试图看看多值mysql插件如何使用hibernate。
String query = "insert into user(age, name, birth_date) values(24, 'Joe', '2010-05-19 14:33:14'), (25, 'Joe1', '2010-05-19 14:33:14')"
getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException, SQLException {
return session.createSQLQuery(query).executeUpdate();
}
});
但是我收到了这个错误: “无法执行本机批量操作查询。”请检查您的查询.....
我是否可以使用Hibernate使用多值mysql插件?或者我的查询不正确?
我可以通过其他方式改善表现吗?我确实尝试过saveOrUpdateAll()方法,这还不够好!
答案 0 :(得分:1)
来自Hibernate的文档中的section 14.1:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
所以,你需要能够传入你试图保持的元组集合,将它们构建为持久对象,然后以某个所需的间隔保存,刷新。
如果这还不够,我建议Hibernate对你要做的事情来说是一个糟糕的解决方案。
答案 1 :(得分:0)
我倾向于仅将Hibernate用于单个对象操作。
对于中型数据量,比如报告,我喜欢Spring JdbcTemplate。
对于非常大的批量插入,我将生成一个带有制表符分隔值的输入文件(在从数据中过滤制表符之后)并使用数据库为批量输入提供的任何shell程序,例如MySql的mysqlimport。这两个步骤可以由不同的机器执行,以扩展大量导入的数据。
答案 2 :(得分:0)
我们使用iBatis在mySQL上获得高性能DML。从另一个抽象层面来看,它比JDBC更好。 iBatis有批处理操作,还包括插入。
只需为这种情况制作另一个特定的DAO接口,并使用iBatis(FooDAO实现FooDAO)实现它。您可以从您的服务中调用新的FooDAO,这会使您的服务调用者看不到它。
答案 3 :(得分:0)
我同意Matthew Flynn的观点。如果您只是直接使用JDBC,那么使用Hibernate没有多大意义。如果您将对象映射为实体,则可以批量使用session.save()持久保存它们,每隔一段时间刷新并清除一次会话,这样就不会耗尽内存。
答案 4 :(得分:-1)
HibernateTemplate有一个bulkUpdate方法,适用于此