JPA/EJB3框架提供标准的批量插入操作方法吗?我们使用Hibernate作为持久化框架,因此可以退回到Hibernate Session并使用session.save() / session.flush()组合实现批量插入。但是我想知道EJB3是否支持这种操作...
JPA/EJB3框架提供标准的批量插入操作方法吗?我们使用Hibernate作为持久化框架,因此可以退回到Hibernate Session并使用session.save() / session.flush()组合实现批量插入。但是我想知道EJB3是否支持这种操作...
既然 JPA 也不提供特定的批量插入支持,因此 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没有任何优势。
如果记录数量较中等,您可以使用以下方法:
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批量存储
如果您希望拥有您定义的控制权,您可以回滚到您的JPA实现。
JPA 1.0在EL-HQL方面非常丰富,但在Criteria API支持方面较轻,不过这在2.0中已得到解决。
Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);
Pascal
在您插入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();
if
语句是否为i > 0 && i % 20 == 0
,否则它将在添加第一个元素后立即刷新(并清除)。 - Buhake Sindi