技术栈: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();
hibernate.cfg.xml
有以下条目
<property name="jdbc.batch_size">500</property>
如何验证 hibernate 是否真的批处理所有这些插入?如果执行 10 次插入,则不会有任何增益。 一种想法是将 jdbc 普通查询放在
save()
之后,检查记录是否已添加到数据库:
String query = "retrieve previously added element"
PreparedStatement stmt = session.connection().prepareStatement(query.toString());
Result rs = statement.executeQuery();
/** check contents of rs */
在我的例子中,它返回一个包含先前添加的元素的非空集。这有什么意义吗?我还能如何检查批处理是否有效。
提前致谢
您需要将“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
要检查实际刷新到数据库的内容,请按如下方式配置日志记录属性:
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();
在 spring boot application.yml 中,我添加了下面的行以查看批处理是否正常工作
logging:
level:
org.hibernate:
engine.jdbc.batch.internal.BatchingBatch: DEBUG
结果我在日志中看到了这样的行
org.jboss.logging.DelegatingBasicLogger: Executing batch size: 30
如果是 Hibernate 6,您需要将
org.hibernate.orm.jdbc.batch
记录器设置为 trace
级别。 (我用 Hibernate 6.5.0.Final 进行了测试。)
Logback配置示例:
<logger name="org.hibernate.orm.jdbc.batch" level="trace"/>
日志输出示例:
2024-05-05 23:00:25 TRACE org.hibernate.orm.jdbc.batch - Executing JDBC batch (3 / 10) - `TestEntity#INSERT`
日志条目的写入方法为:
org.hibernate.engine.jdbc.batch.internal.BatchImpl#performExecution
我在 Hibernate ORM 用户指南中没有找到此信息。