我正在使用jpa和hibernate一起使用seam。我一次只能插入200,000条记录。
这是我的代码:
的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>
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();
以上代码正常运行,但插入200,000条记录大约需要10分钟。我的代码中是否有任何配置可以提高批量插入的性能?
在上面的代码中,我每隔10000条记录执行一次session.flush(),但每次都不插入数据库。你能解释一下如何对db执行批量插入吗?
答案 0 :(得分:1)
在上面的代码中,我每10000条记录执行一次session.flush(),但每次都没有插入数据库。
我认为你的意思是在你到达终点之前,记录似乎并不存在;即它们不会出现在不同交易中的查询中。
如果这是你的意思,那么解释很简单。您正在单个事务中执行插入操作,并且只有在事务提交时才会显示记录...最后。如果您需要将插入更快地显示,请尝试将插入拆分为多个事务。
您还应该阅读有关批处理操作的Hibernate文档 - http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html。我注意到它说合理的批量大小是20到50 ......而不是10000.它还提到了直接使用SQL进行批量数据操作和StatelessSession
的方法。
以下是另一种特定于插入的资源,其中包含StatelessSession
的插入:http://javainnovations.blogspot.com.au/2008/07/batch-insertion-in-hibernate.html
答案 1 :(得分:1)
查看StatelessSession以及如何使用它将项目插入数据库。当问到这个问题时,这似乎是回答的问题,我个人只是用它在15秒内完成了15分钟的工作。它并不适合所有情况,但如果确实如此,那就很有效。
答案 2 :(得分: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