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()
最终,选择是否使用一种方法而不是另一种方法会对应用程序产生很大的性能影响。
0 评论