在Spring DATA JPA的保存(Iterable <s>实体)中命中数据库的次数

时间:2017-08-29 16:59:15

标签: java spring hibernate spring-data-jpa

我有以下几行代码:

@RequestMapping(value="/persons",method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<List<Person>> saveUsers(@RequestBody List<Person> persons) {
        persons = (List<Person>) userRepository.save(persons);
        return new ResponseEntity<List<Person>>(persons, HttpStatus.OK);
}

这是存储库:

@Transactional
public interface UserRepository  extends UserBaseRepository<User> { 
}

@NoRepositoryBean
public interface UserBaseRepository<T extends User> extends CrudRepository<T, Long> {
    public T findByEmail(String email);
}

运行正常。运行代码时,我会看到以下日志。

Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')
Hibernate: insert into user (email, firstname, lastname, user_type) values (?, ?, ?, 'Person')

似乎,DataBase被点击了4次。我已经看到了save(iterable e)方法的实现,其中运行for循环来保存每个实体。所以,我的问题是:

  1. 数据库命中4次?
  2. 如果是这样,那么它可以在1 db命中(使用Spring Data JPA)吗?通过这样做,它会在插入大量记录时提高性能吗?

2 个答案:

答案 0 :(得分:4)

是的,您要四次查询数据。

您可以通过实施Hibernate Batching在一个批处理语句中完成插入。请特别注意执行batch inserts。使用批量插入,您必须通过显式调用会话中的flush()clear()方法来手动控制会话。

另外,考虑设置适当的Hibernate Batching Properties,例如批量大小(默认值为5),以及Hibernate在构造批处理语句之前重新排序插入和更新的权限(如果适用):

hibernate.jdbc.batch_size = 25
hibernate.order_inserts = true
hibernate.order_updates = true

答案 1 :(得分:1)

来自the docs on Hibernate Batching

  

如果,Hibernate会透明地禁用JDBC级别的插入批处理   您使用身份标识符生成器。

因此,如果Person使用Identity生成器(而不是Sequence生成器或TABLE生成器),则不会进行批处理。有关原因,请参阅this section