JPA / EJB3框架是否提供了批量插入操作的标准方法......? 我们使用hibernate作为持久性框架,所以我可以回退到Hibernate Session并使用组合session.save()/ session.flush()实现批量插入。但是想知道EJB3是否支持这个......
答案 0 :(得分:21)
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的任何优势。
答案 1 :(得分:5)
具体来说,对于hibernate,整个chapter 13 of the core manual解释了方法。
但是你说你希望EJB方法通过Hibernate,所以实体管理器文档也有一章关于here。我建议您同时阅读(核心和实体经理)。
在EJB中,它只是关于使用EJB-QL(有一些限制)。如果你需要更多的灵活性,Hibernate提供了更多的机制。
答案 2 :(得分:4)
使用中等记录编号,您可以使用这种方式:
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();
答案 3 :(得分:1)
是的,如果您希望拥有自己定义的控件,可以回滚到JPA实现。
JPA 1.0在EL-HQL上很丰富,但对Criteria API的支持很少,但这已在2.0中得到解决。
Session session = (Session) entityManager.getDelegate();
session.setFlushMode(FlushMode.MANUAL);
答案 4 :(得分: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();