使用JPA EntityManager批量插入

Ran*_*Ran 28 java eclipselink java-ee ejb-3.0

有没有办法我们可以使用JPA EntityManager使用批量插入.我知道没有直接的方法来实现这一目标,但必须有一些方法来实现这一机制.

实际上,对于每次插入操作,它需要300毫秒,我希望使用批量插入而不是单个插入来减少.

这是我正在使用的单个插入代码

        @PersistenceContext(unitName = "testing")
        EntityManager eM;

        Query querys = this.eM.createNativeQuery(insertQuery);
        for (String s : someList) {
            //setting parameters
            querys.executeUpdate();
        }
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Arj*_*jms 23

根据事务是否包含循环,批处理通常已经在您的情况下发生.

JPA将在其L1缓存中收集所有更新,并且通常在事务提交时将所有更新全部写入数据库.这与在JDBC中进行批处理没有什么不同,在您调用更新方法之前,您添加的每个批处理项目也暂时存在于内存中.

可能有问题的是你没有硬性保证JPA确实完成了这个批处理,如果在事务提交或达到阈值时这样做,但我发现在实践中几乎在所有情况下,特别是在涉及这样的情况下简单的更新循环,它确实进行批处理.

一个问题是,即使JPA确实已经进行批处理,您仍然可能希望控制批量大小.通过其他答案链接的文章为此提供了非常有用的信息.

最后,您应该知道您的L1缓存在循环中不断增长,因此如果更新的数量非常大,请定期清除它.或者,如果您的业务逻辑可以维持它,请在多个事务中进行部分更新.例如,交易1中的项目0到100.000,交易2中的项目100.001到200.000等.


Mar*_*tör 17

我知道这是一个相当古老的问题,有一个公认的答案.尽管如此,我想对这个非常具体的主题"JPA批量插入"给出新的答案.

@PersistenceContext
private EntityManager entityManager;

@Value("${hibernate.jdbc.batch_size}")
private int batchSize;

public <T extends MyClass> Collection<T> bulkSave(Collection<T> entities) {
  final List<T> savedEntities = new ArrayList<T>(entities.size());
  int i = 0;
  for (T t : entities) {
    savedEntities.add(persistOrMerge(t));
    i++;
    if (i % batchSize == 0) {
      // Flush a batch of inserts and release memory.
      entityManager.flush();
      entityManager.clear();
    }
  }
  return savedEntities;
}

private <T extends MyClass> T persistOrMerge(T t) {
  if (t.getId() == null) {
    entityManager.persist(t);
    return t;
  } else {
    return entityManager.merge(t);
  }
}
Run Code Online (Sandbox Code Playgroud)

资料来源:http://frightanic.com/software-development/jpa-batch-inserts/

  • 我想我们需要再次使用`flush()`和`clear()`来保存任何未完成批量大小的剩余对象? (4认同)

Ósc*_*pez 12

可以进行使用JPA成批写操作,但它是高度依赖于具体的实现你的持久性提供数据库和JDBC驱动程序.例如,本文解释了如何使用EclipseLink JPA 2.3和Oracle数据库启用批量写入(优化#8).查看特定环境中的类似配置参数.

  • @Rana全部在链接文章中,您必须编辑`persistence.xml`文件并添加类似`<property name ="eclipselink.jdbc.batch-writing"value ="JDBC"/> <property name =" eclipselink.jdbc.batch-writing.size"value ="1000"/>`.请花点时间先阅读这篇文章. (4认同)