Java CrudRepository和Hibernate:在事务中保存(列表<;S>;)与保存(实体)
如果我这样做会有什么不同吗:Java CrudRepository和Hibernate:在事务中保存(列表<;S>;)与保存(实体),java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,如果我这样做会有什么不同吗: @Transactional public void processData() { List<MyEntity> entities = ....; MyEntityRepository.save(entities); } @Transactional public void processData(){ 列出实体=。。。。; MyEntityRepository.save(实体); } vs @Transactional publi
@Transactional
public void processData() {
List<MyEntity> entities = ....;
MyEntityRepository.save(entities);
}
@Transactional
public void processData(){
列出实体=。。。。;
MyEntityRepository.save(实体);
}
vs
@Transactional
public void processData(){
列出实体=。。。。;
for(MyEntity实体:实体){
MyEntityRepository.save(实体);
}
}
在基础查询和性能方面有什么区别?来自
SimpleParepository
:
@Transactional
public <S extends T> List<S> More 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;
}
@Transactional
公共列表更多保存(Iterable实体){
列表结果=新建ArrayList();
如果(实体==null){
返回结果;
}
对于(S实体:实体){
结果.添加(保存(实体));
}
返回结果;
}
因此,您的第二个业务方法只会隐藏save(Iterable entities)
Crud存储库方法,因为它会迭代列表并代表您调用save
只要将事务与您的
processData
业务方法区分开来,在性能或执行的查询方面就没有真正的区别。正如前面提到的,没有真正的区别
但是,有一点您应该注意:用于保存元素列表的方法已根据重命名为中的list saveAll(Iterable entities)
,并且save
方法不再将列表作为参数
由于我没有资格对上述答案或问题发表评论,我必须就这一变化写一个新的答案。对于SpringData Jpa,一个更干净的方法是使用
存储库。saveAll
而不是For
循环存储库。save
saveAll
将自动遍历列表并保存它
saveAll
是JpaRepository的一部分,因此无需定义任何方法。如果我的列表包含具有相同主键的多个实体,然后我调用save(list Entities)
,则会给出约束异常。但是,如果我迭代(即第二个业务方法),它不会抱怨。为什么?很有趣。我的猜测是,@Transactional
不适用于processData()
,因此在第二个变体中,每个迭代都在它自己的事务上下文中运行,因此成功。@AshishLohia save方法可以将单个对象或对象列表用作参数。你可以认为它会有帮助,因为它是“批量插入”,但正如你在上面看到的那样,情况并非如此。
@Transactional
public <S extends T> List<S> More 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;
}