23

JPA/EJB3 框架是否提供标准方式来执行批量插入操作...?我们使用hibernate作为持久化框架,所以我可以回退到Hibernate Session并使用组合session.save()/session.flush()实现批量插入。但是想知道EJB3是否支持这个......

4

5 回答 5

22

JPA 和 Hibernate 都没有为批量插入提供特别的支持,使用 JPA 进行批量插入的习惯用法与使用 Hibernate 相同:

EntityManager em = ...;
EntityTransaction tx = em.getTransaction();
tx.begin();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    em.persist(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        em.flush();
        em.clear();
    }
}

tx.commit();
session.close();

在这种情况下使用 Hibernate 的专有 API 不会提供任何优势 IMO。

参考

  • JPA 1.0 规范
    • 第 4.10 节“批量更新和删除操作”
  • Hibernate Core 参考指南
于 2010-09-02T01:26:11.307 回答
5

特别是对于hibernate,核心手册的整个第13章解释了这些方法。

但是您说您希望通过 Hibernate 使用 EJB 方法,因此实体管理器文档在此处也有一章。我建议您同时阅读(核心和实体管理器)。

在 EJB 中,它只是关于使用 EJB-QL(有一些限制)。如果您需要更多灵活性,Hibernate 会提供更多机制。

于 2009-01-15T20:05:04.753 回答
5

使用中等记录数,您可以使用这种方式:

em.getTransaction().begin();
for (int i = 1; i <= 100000; i++) {
     Point point = new Point(i, i);
     em.persist(point);
     if ((i % 10000) == 0) {
          em.flush();
          em.clear();
     }
}
em.getTransaction().commit();

但是对于大量记录,您应该在多个事务中执行此任务:

em.getTransaction().begin();
for (int i = 1; i <= 1000000; i++) {
      Point point = new Point(i, i);
      em.persist(point);
      if ((i % 10000) == 0) {
          em.getTransaction().commit();
          em.clear();          
          em.getTransaction().begin();
      }
}
em.getTransaction().commit();

参考:JPA 批量存储

于 2014-04-03T05:00:47.620 回答
1

是的,如果您希望获得您定义的控制权,您可以回滚到您的 JPA 实现。

JPA 1.0 对 EL-HQL 的支持很丰富,但对 Criteria API 的支持很简单,但是这已在 2.0 中得到解决。

Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);
于 2009-07-06T10:27:58.333 回答
1

帕斯卡

在您插入 100000 条记录的示例中,它是在单个事务中完成的,因为 commit() 仅在最后被调用。它是否给数据库带来了很大的压力?此外,万一有回滚,成本会太大..

以下方法会更好吗?

EntityManager em = ...;
for ( int i=0; i<100000; i++ ) {
   if(!em.getTransaction().isActive()) {
      em.getTransaction().begin();
   }
   Customer customer = new Customer(.....);
   em.persist(customer);
   if ((i+1) % 20 == 0 ) { //20, same as the JDBC batch size
      //flush and commit of inserts and release memory:
      em.getTransaction().commit(); 
      em.clear();
   }
}

session.close();
于 2013-12-13T15:30:43.453 回答