2017-07-27 47 views
0

方法有效性當與Java 8一起使用Spring的數據,我們有兩個選擇保存該集合:春數據JPA保存在Java中8個功能地圖

  1. 我們可以用經典List<S> save(Iterable<S> entities)方法,它的整個列表。
    實施例:

    someOtherRepository.save(
        someRepository.findAll() 
        .stream() 
        .map(something -> { 
         //some operations 
         return someOtherThing; 
        }) 
        .collect(Collectors.toList()) 
    ); 
    
  2. 我們可以使用S save(S entity)方法,它採用單一實體,並在map使用它在一個stream
    實施例:

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

的問題是:
是否有在這兩個方法之間執行時間的差?如果是,哪個更有效(更快)。

回答

2

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; 
} 

於是兩人應該給予同樣的結果在性能方面。

要進行批量插入,您必須在您的休眠配置(hibernate.jdbc.batch_size)中指定它並自行處理刷新。

1

在有一個以上的元素列表的情況下,第一種方法會快很多(如果列表只有一個元素,它應該是相同的)

只是簡要描述了原因。在批量插入過程中,您不會因多次單插入而建立多重連接的開銷。

+0

你能詳細描述一下嗎?我不相信每一次使用save方法都會使數據庫有新的連接。它可能發生在編寫不好的JDBC代碼中,但是hibernate有一個連接池。特別是在閱讀另外兩個答案之後,我不相信你的答案。 – luke

2

這取決於很多事情,因此很難預測。但我希望它不會有太大的區別。

由於問題標記爲hibernate,因此您似乎在討論Spring Data JPA。假設您的交易跨越了所有對save的調用,保存實際上只是將該實體添加到EntityManager而不實際訪問數據庫。當最後一次刷新發生時(通常在事務結束時),所有實體將一直由Hibernate持久保存到數據庫。

因此,性能差異來自您的代碼和Spring Data中的不同代碼路徑。這些差異應該來自實際上持續存在的實體的任何事物。

如果我們在談論大量實體,那麼EntityManager本身的性能特徵可能會變得相關。

如果每次致電save創建自己的事務,單個調用很可能會慢得多。

所以最終,它歸結爲:

你爲什麼不只是你的數據試試嗎?讓我們知道結果?