Spring Data中save和saveAll方法之間的性能差異

1.概述

在本快速教程中,我們將學習Spring Data中save()saveAll()

2.應用程序

為了測試性能,我們需要一個帶有實體和存儲庫的Spring應用程序。

讓我們創建一個圖書實體:

@Entity

 public class Book {



 @Id

 @GeneratedValue(strategy = GenerationType.AUTO)

 private long id;



 private String title;

 private String author;



 // constructors, standard getters and setters

 }

另外,讓我們為其創建一個存儲庫:

public interface BookRepository extends JpaRepository<Book, Long> {

 }

3.測試性能

為了測試性能,我們將使用這兩種方法保存10,000本書。

首先,我們將使用save()方法:

for(int i = 0; i < bookCount; i++) {

 bookRepository.save(new Book("Book " + i, "Author " + i));

 }

然後,我們將創建一個書籍列表,並使用saveAll()方法一次保存所有書籍:

List<Book> bookList = new ArrayList<>();

 for (int i = 0; i < bookCount; i++) {

 bookList.add(new Book("Book " + i, "Author " + i));

 }



 bookRepository.saveAll(bookList);

在我們的測試中,我們注意到第一種方法花費了大約2秒鐘,第二種方法花費了大約0.3秒。

此外,啟用JPA批處理插入時,我們發現save()方法的性能最多降低10%,而saveAll()方法的性能最多降低60%。

4.差異

查看這兩種方法的實現,我們可以看到saveAll()遍歷每個元素,並在每次迭代中save()這意味著它應該不會有太大的性能差異。

仔細觀察,我們發現這兩種方法都使用@Transactional進行了註釋。

此外,默認的事務傳播類型為REQUIRED,這意味著,如果未提供,則每次調用方法時都會創建一個新的事務

在我們的例子中,每次我們調用save()方法時,都會創建一個新事務,而當我們調用saveAll() ,只會創建一個事務,稍後將由save()重用。

這種開銷轉化為我們之前註意到的性能差異。

最後,啟用批處理時的開銷會更大,這是因為它是在事務級別完成的。

5.結論

在本文中,我們了解了Spring Data中save()saveAll()

最終,選擇是否使用一種方法而不是另一種方法會對應用程序產生很大的性能影響。