我需要hibernate来生成像这样INSERT INTO table_a (a_id, a_name) VALUES (5, 'a5'),(6, 'a6');
的SQL。
使用这样的sql,你可以添加2行1个语句。我可以得到
a_id, a_name
------------------
5 a5
6 a6
当处于休眠状态时,当您保存一对多关系的集合时,hibernate将插入多个插入语句。这将导致如果您使用HQL将1000行插入到1个表中,将导致如下所示:
INSERT INTO scoring.table_a (`a_id`, `a_name`) VALUES (1, 'a');
INSERT INTO scoring.table_a (`a_id`, `a_name`) VALUES (2, 'a');
....
...
..
INSERT INTO scoring.table_a (`a_id`, `a_name`) VALUES (1000, 'a');
经过的时间是:
Executed 1,000 queries; elapsed time (seconds) - Total: 0.78, SQL query: 0.78, Building output: 0
当我使用相同的值进行测试时,使用SQL INSERT INTO table_a (a_id, a_name) VALUES (5, 'a'),(6, 'a'),(),...,...,(1000, 'a');
将导致如下所示的经过时间:
Query 1 of 1, Rows read: 0, Elapsed time (seconds) - Total: 0.02, SQL query: 0.02, Building output: 0
我的测试结果是,1000个值(0.02s)的声明将比1000个插入语句快39倍,每个都有像hibernate那样的1个值(0.78s)。那么是否有一种方法可以使HQL生成类似于插入或可能更新的SQL。或者这意味着我们必须覆盖hibernate方言吗?
感谢任何提示
答案 0 :(得分:0)
您可以将hibernate.jdbc.batch_size
属性设置为非零值。它将允许Hibernate使用批处理INSERT。看看a official documentation。
以下代码是如何通过Hibernate使用JDBC批量插入的示例:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i < 10000; i++ ) {
RecordA record = new RecordA(.....);
session.save(record);
if ( i % BATCH_SIZE == 0 ) { // BATCH_SIZE is your choice, but equal to property
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
答案 1 :(得分:0)
HQL仅支持 INSERT INTO ......... SELECT ......... ;没有机会写 INSERT INTO ......... VALUES ,我的意思是在编写插入查询时,我们需要从其他表中选择值,我们不能手动插入我们自己的值。 (see documentation和this)