2

我正在使用 jpa 和使用 seam 的休眠。一次需要插入 200,000 条记录。

这是我的代码:

休眠.cfg.xml

<hibernate-configuration>
 <session-factory name="java:/mobeeSessionFactory">
  <property name="hibernate.connection.pool_size">10</property>
  <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
  <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:mobee</property>
  <property name="hibernate.connection.username">mobeemigrate</property>
  <property name="hibernate.connection.password">mobeemigrate</property>
  <property name="hibernate.show_sql">false</property>
  <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
  <property name="hibernate.format_sql">false</property>
  <property name="hibernate.hbm2ddl.auto">update</property>
  <property name="hibernate.session_factory_name">java:/mobeeSessionFactory</property>
  <property name="hibernate.connection.datasource">mobeeadminDataSource</property>
  <property name="hibernate.jdbc.batch_size">10000</property>
  <property name="hibernate.cache.use_first_level_cache">true</property>
  <property name="hibernate.cache.use_second_level_cache">false</property>
  <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
  <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
  <property name="hibernate.transaction.auto_close_session">false</property>
  <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
  <property name="hibernate.transaction.flush_before_completion">true</property>

  <!-- Here are the mappings -->
  <mapping package="com.manam.mobee.persist.entity"/>
  <mapping class="com.manam.mobee.persist.entity.TempCustomers"/>
  <mapping class="com.manam.mobee.persist.entity.TempAccounts"/>
 </session-factory>

组件.xml

<persistence:hibernate-session-factory name="hibernateSessionFactory" cfg-resource-name="hibernate.cfg.xml"/>
    <persistence:managed-hibernate-session name="session" 
                 auto-create="true"
     session-factory-jndi-name="java:/mobeeSessionFactory"/>

示例代码:

 Session session =hibernateSessionFactory.openSession();
             Transaction tx = session.beginTransaction();

   for(int i=0;i<doTempAccounts.size();i++){

     try {
    TempAccounts temp=new TempAccounts();

    BeanUtils.copyProperties(temp, doTempAccounts.get(i));

    session.save(temp);

    if ( i % 10000 == 0 ) { //10000, same as the JDBC batch size
     //flush a batch of inserts and release memory:
    log.info("********** Batch Updates**********");
    session.flush();
    session.clear();
     }
     }
     }
    tx.commit();
    session.close();

上面的代码可以运行,但是插入 200,000 条记录大约需要 10 分钟。我的代码中是否有任何配置可以提高批量插入的性能?

在上面的代码中,我每 10000 条记录执行一次 session.flush(),但不是每次都插入数据库。你能解释一下如何对数据库执行批量插入吗?

4

3 回答 3

1

在上面的代码中,我每 10000 条记录执行一次 session.flush(),但不是每次都插入数据库。

我想您的意思是,直到您到达终点,记录才出现在那里;即它们不会出现在不同事务中的查询中。

如果这就是你的意思,那么解释很简单。您正在单个事务中进行插入,并且记录仅在事务提交时才可见......在最后。如果您需要更快地看到插入,请尝试将插入拆分为多个事务。


您还应该阅读有关批处理操作的 Hibernate 文档 - http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html。我注意到它说合理的批量大小是 20 到 50 ...而不是 10000。它还提到了直接使用 SQL 进行批量数据操作的方法和StatelessSession.

这是另一个特定于插入的资源,包括插入:http StatelessSession: //javainnovations.blogspot.com.au/2008/07/batch-insertion-in-hibernate.html

于 2012-12-08T00:24:47.777 回答
1

查看 StatelessSession 以及如何使用它将项目插入数据库。当被问到这个问题时,这似乎是答案,我个人只是用它在大约 15 秒内完成了 15 分钟的工作。它并不适合所有场景,但如果适合,它会很好用。

于 2012-12-08T00:49:46.010 回答
0

您可以使用几乎与 SQL 中相同的方式来执行此操作。请看以下 HQL 示例:

insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...

参考:http ://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch04.html#d0e2184

于 2014-07-18T13:24:44.420 回答