Session.Save 是否正在向数据库发送请求?

Is Session.Save sending a request to the database?

我必须提高一个非常慢的代码的性能,而且我是 Hibernate 的新手。我仔细研究了代码并得出结论,问题在于它有大量实体要加载和 update/insert。为了将算法转换为更易于理解的示例,假设我们有这样一个算法:

for each competitionToSave in competitionsToSave
    competition <- load a Competition by competitionToSave from database

    winner <- load Person by competitionToSave.personID

    do some preprocessing

    if (newCompetition) then
        insert competition
    else
        update competition
    end if
end for

competitionToSave中有很多competition时,这个算法当然是有问题的。所以,我的计划是select所有涉及到两个数据库请求最多的competitions和winners,预处理数据,这将加快读取速度,但更重要的是,确保我将通过 insert/update 批次保存 100 competitions 而不是单独保存它们。由于我是 Hibernate 的新手,我查阅了 documentation 并找到了以下示例:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    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();
session.close();

但是,我不确定我是否理解正确。关于方法 .save() 我看了:

Persist the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.) This operation cascades to associated instances if the association is mapped with cascade="save-update".

但我不清楚是否每隔 save 就向数据库发送一次请求。如果我假设在取自文档的示例中 session.save(customer) 将对象的修改保存在 Session 中而不 向数据库发送请求并且然后在每第 20 个项目上 session.flush() 向数据库发送请求并且 session.clear() 删除 Session?

的缓存

你的假设是正确的,尽管插入将被一个接一个地触发:

insert into Customer(id , name) values (1, 'na1');
insert into Customer(id , name) values (2, 'na2');
insert into Customer(id , name) values (3, 'na3'); 

您可以尝试利用批量插入功能来进一步提高性能。

有 hibernate 属性,您可以将其定义为 hibernate 的属性之一 SessionFactory:

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

使用这个批处理设置,每次刷新后你应该有这样的输出:

insert into Customer(id , name) values (1, 'na1') , (2, 'na2') ,(3, 'na3')..

一个插入而不是二十个。