Java 如何使用会话工厂提高批量插入的性能

Java 如何使用会话工厂提高批量插入的性能,java,hibernate,session,seam,Java,Hibernate,Session,Seam,我使用jpa,hibernate使用seam。我需要一次插入200000条记录 这是我的密码: hibernate.cfg.xml <hibernate-configuration> <session-factory name="java:/mobeeSessionFactory"> <property name="hibernate.connection.pool_size">10</property> <property nam

我使用jpa,hibernate使用seam。我需要一次插入200000条记录

这是我的密码:

hibernate.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>

10
oracle.jdbc.OracleDriver
jdbc:oracle:thin:@localhost:1521:mobee
mobeemigrate
mobeemigrate
假的
org.hibernate.dialen.oraclealent
假的
更新
java:/mobeeSessionFactory
mobeeadminDataSource
10000
真的
假的
org.hibernate.transaction.JBossTransactionManagerLookup
org.hibernate.transaction.JTATransactionFactory
假的
org.hibernate.cache.HashtableCacheProvider
真的
component.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();
会话会话=hibernateSessionFactory.openSession(); 事务tx=会话.beginTransaction(); 对于(int i=0;i 在上面的代码中,我每10000条记录执行一次session.flush(),但不是每次都插入数据库

我想你的意思是,在你到达终点之前,记录不会出现在那里;也就是说,它们不会出现在不同事务中的查询中

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


您还应该阅读有关批处理操作的Hibernate文档-。我注意到它说合理的批处理大小是20到50…而不是10000。它还提到了直接使用SQL进行批处理数据操作和无状态会话的方法


这是另一个专门针对插入的资源,包括使用
无状态会话插入

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

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

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

参考资料:

查看大容量无状态会话operations@AffeThanx对于响应,我将进行检查,我有一个疑问,在这个会话中,我将刷新每10000条记录中的db,但为什么它没有每次插入db?Thanx响应您能告诉我如何使用无状态会话插入记录吗?因为我在无状态会话中找不到保存方法sion..@nag-阅读我答案中的链接。它有无状态会话的示例代码。@Steohen我在那个无状态会话中看到了这个示例,他们从session.getNamedQuery中获取记录,在我的senario中,他们从.csv文件中获取数据并存储到arrayList。如何使用无状态会话接口读取arrayList数据