Bla*_*man 7 java orm hibernate data-processing
我正在使用hibernate来更新我的数据库中的20K产品.
截至目前,我正在提取20K产品,循环遍历它们并修改一些属性,然后更新数据库.
所以:
load products
foreach products
session begintransaction
productDao.MakePersistant(p);
session commit();
Run Code Online (Sandbox Code Playgroud)
截至目前,与标准的jdbc相比,事情相当缓慢,我该怎么做才能加快速度?
我相信我在这里做错了什么.
Pas*_*ent 10
在这种处理的文档中查看的正确位置是整个第13章.批处理.
在这里,您当前的方法有几个明显的错误:
你应该启用JDBC批处理并将其设置为合理的数字(10-50):
hibernate.jdbc.batch_size 20
Run Code Online (Sandbox Code Playgroud)你应该flush()然后clear()定期会话(每n个记录,其中n等于hibernate.jdbc.batch_size参数),或者它会继续增长,并且可能会OutOfMemoryException在某个时刻爆炸(带有a ).
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers")
.setCacheMode(CacheMode.IGNORE)
.scroll(ScrollMode.FORWARD_ONLY);
int count=0;
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
if ( ++count % 20 == 0 ) {
//flush a batch of updates and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
Run Code Online (Sandbox Code Playgroud)
您也可以考虑使用StatelessSession.
另一种选择是使用DML风格的操作(在HQL!) UPDATE FROM? EntityName (WHERE where_conditions)?.这是HQL UPDATE示例:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
Run Code Online (Sandbox Code Playgroud)
再次,请参阅文档以获取详细信息(特别是如何使用关键字处理version或timestamp属性值VERSIONED).
如果这是伪代码,我建议在循环外移动事务,或者如果单个事务中的所有20K产品都太多,则至少要有一个双循环:
load products
foreach (batch)
{
try
{
session beginTransaction()
foreach (product in batch)
{
product.saveOrUpdate()
}
session commit()
}
catch (Exception e)
{
e.printStackTrace()
session.rollback()
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我建议您批量更新UPDATE,而不是将每个UPDATE单独发送到数据库.这样的网络流量太多了.将每个块捆绑成一个批次并立即发送它们.
| 归档时间: |
|
| 查看次数: |
832 次 |
| 最近记录: |