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

13

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

我对Hibernate不熟悉,如果这很简单请见谅。

以下代码应该实现了一些优化:

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

hibernate.cfg.xml 有以下条目

<property name="jdbc.batch_size">500</property>

如何验证Hibernate是否真正批量插入了这些记录?如果它只执行了10次插入,那就没有优势。 一个想法是在 save() 后面放置jdbc纯查询,以检查记录是否已添加到数据库:

如何验证Hibernate是否真正批量插入了这些记录?如果它只执行了10次插入,那就没有优势。 一个想法是在 save() 后面放置jdbc纯查询,以检查记录是否已添加到数据库:

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

在我的情况下,它返回了一个非空集合,其中包含先前添加的元素。这意味着什么?还有其他方法可以检查批处理是否起作用。

谢谢提前


重构后添加事务方法的代码。 - Maciej Kowalski
1
很抱歉,我不太明白。 - Łukasz
3个回答

20

你需要向日志提供程序添加“BatchingBatch”记录器。

org.hibernate.engine.jdbc.batch.internal.BatchingBatch

然后你就能在日志中看到类似以下的内容:

2018-02-20 17:33:41.279 DEBUG 6280 --- [           main] o.h.e.jdbc.batch.internal.BatchingBatch  : Executing batch size: 19

如果您看不到这条消息,批处理功能将无法正常工作。

使用的 Hibernate 版本:5.2.12


@Frans - 我使用的是 Hibernate 3.6.6。 - Łukasz

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

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

<property name="show_sql">true</property>

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

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

insert into Pojo (id , titel) values (1, 'val1') , (2, 'val2') ,(3, 'val3')

此外,这是一篇关于如何最有效地利用批处理的技巧的好文章:文章
例如,您可以在每个${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();

谢谢。不幸的是,我仍然只看到单个插入语句。 - Łukasz
你在保存 ${jdbc.batch_size} 条数据后是否进行了刷新? - Maciej Kowalski
2
如果您的JDBC驱动程序支持,INSERT语句将仅被重写为大型批量INSERT(我知道MySQL可以做到这一点)。然而,这是与批处理插入不同的问题。您可以在日志中看到单个插入,但它们仍然可以作为批处理发送到服务器。 - Frans
对于MYSQL(版本5.x),它在日志中显示单个插入,但在统计日志中显示执行的(n)批语句。 - John
@John,MYSQL进程列表中只会显示单个插入语句列表吗?还是应该显示完整批处理的执行情况? - Sumit Desai

0
在Spring Boot的application.yml中,我添加了以下行以查看批处理是否正常工作。
logging:
  level:
    org.hibernate:
      engine.jdbc.batch.internal.BatchingBatch: DEBUG

结果,我在日志中看到了这样的行

org.jboss.logging.DelegatingBasicLogger: Executing batch size: 30

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接