Hibernate - 如何验证是否真正执行批量插入

Łuk*_*asz 4 java oracle orm hibernate batch-insert

技术堆栈:Oracle数据库11.2.0.2,Java 1.6,Hibernate 3.6.6.Final.

我是新来的冬眠,如果这是微不足道的话道歉.

以下代码应该进行一些优化:

Transaction tx = session.beginTransaction();
for (int i = 0; i < 10; i++) {
   POJO pojo = new POJO(i);
   session.save(pojo);
}
tx.commit();
Run Code Online (Sandbox Code Playgroud)

hibernate.cfg.xml 有以下条目

<property name="jdbc.batch_size">500</property>
Run Code Online (Sandbox Code Playgroud)

如果hibernate真的批量所有这些插入,我如何验证?如果它执行10次插入而不是没有增益.一个想法是在save()检查记录是否已添加到db 之后立即放置jdbc普通查询:

String query = "retrieve previously added element"
PreparedStatement stmt = session.connection().prepareStatement(query.toString());
Result rs = statement.executeQuery();
/** check contents of rs */
Run Code Online (Sandbox Code Playgroud)

在我的例子中,它返回一个非空集与先前添加的元素.这有什么意义吗?我怎样才能检查批处理是否有效.

提前致谢

sel*_*man 9

您需要将"BatchingBatch"记录器添加到日志记录提供程序.

org.hibernate.engine.jdbc.batch.internal.BatchingBatch
Run Code Online (Sandbox Code Playgroud)

你可以在日志中看到类似的东西:

2018-02-20 17:33:41.279 DEBUG 6280 --- [           main] o.h.e.jdbc.batch.internal.BatchingBatch  : Executing batch size: 19
Run Code Online (Sandbox Code Playgroud)

除非您看到此消息,否则批处理不起作用.

使用Hibernate版本进行测试:5.2.12


Mac*_*ski 2

要检查实际刷新到数据库的内容,请按如下方式配置日志记录属性:

log4j.rootLogger=info, stdout
# basic log level for all messages
log4j.logger.org.hibernate=debug

# SQL statements and parameters
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.type.descriptor.sql=trace
Run Code Online (Sandbox Code Playgroud)

并将其添加到您的 hibernate.cfg.xml 中

<property name="show_sql">true</property>
Run Code Online (Sandbox Code Playgroud)

然后你可以看到实际发送到数据库的内容..

使用批处理,您应该得到如下输出:

insert into Pojo (id , titel) values (1, 'val1') , (2, 'val2') ,(3, 'val3')
Run Code Online (Sandbox Code Playgroud)

此外,这里有一篇很好的文章,其中提供了一些有关如何最有效地利用批处理的提示:文章

例如,您可能会考虑在每次 ${jdbc.batch_size} 保存后刷新。

Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    Cart cart = new Cart(...);
    customer.setCart(cart) // note we are adding the cart to the customer, so this object 
     // needs to be persisted as well
    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();
Run Code Online (Sandbox Code Playgroud)

  • 仅当您的 JDBC 驱动程序支持时,INSERT 语句才会被重写为大批量 INSERT(我知道 MySQL 可以做到这一点)。然而,这是与批量插入不同的问题。您可以在日志中看到单个插入,但它们仍然可以批量发送到服务器。 (2认同)