如何使HQL生成SQL以在一个语句中插入多个值?

Ang*_*gga 6 mysql optimization performance hibernate hql

我需要hibernate来生成这样的sql INSERT INTO table_a (a_id, a_name) VALUES (5, 'a5'),(6, 'a6');.

使用类似的sql,你可以添加2行1语句.我可以得到

a_id, a_name

------------------
5     a5
6     a6
Run Code Online (Sandbox Code Playgroud)

在hibernate中,当你保存一对多关系的集合时,hibernate会插入多个insert语句.这将导致如果您使用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');
Run Code Online (Sandbox Code Playgroud)

经过的时间是:

Executed 1,000 queries; elapsed time (seconds) - Total: 0.78, SQL query: 0.78, Building output: 0
Run Code Online (Sandbox Code Playgroud)

当我使用相同的值进行测试时,使用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
Run Code Online (Sandbox Code Playgroud)

我测试的结果是,1000个值(0.02s)的1个语句将比1000个insert语句快39倍,每个语句都有1个值(0.78s),就像hibernate一样.那么是否有一种方法可以使HQL生成类似于插入或可能更新的SQL.或者这意味着我们必须覆盖hibernate方言?

谢谢你的任何提示

小智 0

您可以将hibernate.jdbc.batch_size属性设置为非零值。它将允许 Hibernate 使用批量 INSERT。看一下官方文档

以下代码是如何通过 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();
Run Code Online (Sandbox Code Playgroud)

这里也讨论了:Hibernate批量大小混淆