简体   繁体   English

Spring Data JPA在Java 8功能图中节省方法的有效性

[英]Spring Data JPA save method effectiveness in Java 8 functional map

When using Spring Data together with Java 8 we have two options to save the collection: 当将Spring Data与Java 8结合使用时,我们有两种选择来保存集合:

  1. We can use classic List<S> save(Iterable<S> entities) method that takes the whole list. 我们可以使用经典的List<S> save(Iterable<S> entities)方法来获取整个列表。
    Example: 例:

     someOtherRepository.save( someRepository.findAll() .stream() .map(something -> { //some operations return someOtherThing; }) .collect(Collectors.toList()) ); 
  2. We can use S save(S entity) method that takes single entity and use it in a stream in a map . 我们可以使用采用单个实体并在map stream中使用它的S save(S entity)方法。
    Example: 例:

     someRepository.findAll() .stream() .map(something -> { //some operations return someOtherThing; }) .map(someOtherRepository::save) .collect(Collectors.toList()); 

The question is: 问题是:
Is there a difference in execution time between those two approaches? 这两种方法之间的执行时间是否有所不同? If yes which is more effective (faster). 如果是,那更有效(更快)。

It depends on many things and therefore is hard to predict. 它取决于许多事情,因此很难预测。 But I would expect it not to make much of a difference. 但是我希望它不会带来太大的改变。

You seem to be talking Spring Data JPA here since the question is tagged with hibernate . 您似乎在这里说的是Spring Data JPA,因为问题是用hibernate标记的。 Assuming your transaction spans all the calls to save , saving really just adds the entity to the EntityManager without actually accessing the database. 假设您的事务涉及到所有的save调用,则save实际上只是将实体添加到EntityManager而不实际访问数据库。 And when finally a flush happens (typically at the end of the transaction), all entities will get persisted to the database in one go by Hibernate. 当最终发生刷新时(通常在事务结束时),Hibernate一次性将所有实体持久化到数据库中。

Therefore performance differences come from the different code paths in your code and in Spring Data. 因此,性能差异来自代码和Spring Data中不同的代码路径。 Those differences should be neglectable from anything coming from actually persisting entities. 这些差异应该从实际存在的实体中忽略不计。

If we are talking about huge numbers of entities the performance characteristics of the EntityManager itself might become relevant. 如果我们谈论的是大量实体,则EntityManager本身的性能特征可能会变EntityManager重要。

If every call to save creates its own transaction single calls will most likely be much slower. 如果每个save请求都创建了自己的事务,则单个调用很可能会慢得多。

So in the end, it boils down to: 因此,最终归结为:

Why don't you just try it with your data? 您为什么不随便尝试一下数据呢? And let us know the results? 让我们知道结果吗?

save(Iterable<S> entities) relies on iterating and invoking save(S entity) : save(Iterable<S> entities)依赖于迭代和调用save(S entity)

@Transactional
public <S extends T> List<S> save(Iterable<S> entities) {

    List<S> result = new ArrayList<S>();

    if (entities == null) {
        return result;
    }

    for (S entity : entities) {
        result.add(save(entity));
    }

    return result;
}

So the two should give the same result in terms of performance. 因此,两者在性能方面应给出相同的结果。

To do batch insert, you have to specify it in your hibernate configuration ( hibernate.jdbc.batch_size ) and handle yourself the flush. 要进行批量插入,您必须在hibernate配置中指定它( hibernate.jdbc.batch_size )并自己进行刷新。

In case of the list with more than one element, the first approach will be much faster (if the list is has just one element, it should be the same) 如果列表中有多个元素,则第一种方法会快得多(如果列表中只有一个元素,则应该相同)

Just briefly describing the reason why. 只需简要说明原因。 During batch insert you will not have the overhead of multiple connection established with single insert multiple time. 在批量插入过程中,您将无需多次插入一次即可建立多个连接的开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM