Hibernate的批量操作

Posted JustDo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate的批量操作相关的知识,希望对你有一定的参考价值。

在实际的操作中,会经常的遇到批量的操作,使用hibernate将 100条记录插入到数据库的一个很自然的做法可能是这样的

1 Session session = sessionFactory.openSession();
2 Transaction tx = session.beginTransaction();
3 for ( int i=0; i<100; i++ ) {
4     User user= new User(.....);
5     session.save(user);
6 }
7 tx.commit();
8 session.close();

 

这样看起来似乎也没有太大的问题,但是我们设想一下,如果现在批量的操作是100000,或者更多,问题就出现了,这段程序大概运行到 50 000 条记录左右会失败并抛出 内存溢出异常(OutOfMemoryException) 。 这是因为 Hibernate 把所有新插入的 用户(User)实例在 session级别的缓存区进行了缓存的缘故。

  实际操作中避免这样的情况很有必要, 那么使用JDBC的批量(batching)功能是至关重要,将JDBC的批量抓取数量(batch size)参数设置到一个合适值 (比如,10-50之间):

hibernate.jdbc.batch_size 20

你也可能想在执行批量处理时关闭二级缓存:

hibernate.cache.use_second_level_cache false  

 

批量插入(Batch inserts) 
 1 Session session = sessionFactory.openSession();
 2 Transaction tx = session.beginTransaction();
 3    for ( int i=0; i<100000; i++ ) {
 4     User user= new User(.....);
 5     session.save(user);
 6     if ( i % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同
 7         //flush a batch of inserts and release memory:
 8         //将本批插入的对象立即写入数据库并释放内存
 9         session.flush();
10         session.clear();
11     }
12 }
13    
14 tx.commit();
15 session.close();

 

批量更新(Batch update)

此方法同样适用于检索和更新数据。此外,在进行会返回很多行数据的查询时, 你需要使用 scroll() 方法以便充分利用服务器端游标所带来的好处。

 1 Session session = sessionFactory.openSession();
 2 Transaction tx = session.beginTransaction();
 3    
 4 ScrollableResults users = session.getNamedQuery("GetUsers")
 5     .setCacheMode(CacheMode.IGNORE)
 6     .scroll(ScrollMode.FORWARD_ONLY);
 7 int count=0;
 8 while ( users.next() ) {
 9     User user= (User) users.get(0);
10     user.updateStuff(...);
11     if ( ++count % 20 == 0 ) {
12         //flush a batch of updates and release memory:
13         session.flush();
14         session.clear();
15     }
16 }
17 
18    
19 tx.commit();
20 session.close();

 

大批量更新/删除(Bulk update/delete)
使用Query.executeUpdate()方法执行一个HQL UPDATE语句: 
 1 Session session = sessionFactory.openSession();
 2         Transaction tx = session.beginTransaction();
 3 
 4         String hqlUpdate = "update User set name = :newName where name = :oldName";
 5         int updatedEntities = s.createQuery( hqlUpdate )
 6                             .setString( "newName", newName )
 7                             .setString( "oldName", oldName )
 8                             .executeUpdate();
 9         tx.commit();
10         session.close();

 

执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法 (此方法是为 那些熟悉JDBC PreparedStatement.executeUpdate() 的人们而设定的)

1 Session session = sessionFactory.openSession();
2         Transaction tx = session.beginTransaction();
3 
4         String hqlDelete = "delete User where name = :oldName";
5         int deletedEntities = s.createQuery( hqlDelete )
6                             .setString( "oldName", oldName )
7                             .executeUpdate();
8         tx.commit();
9         session.close();

 

以上是关于Hibernate的批量操作的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 中批量处理数据

Hibernate的批量操作

Hibernate的批量操作

使用 EntityManager / Hibernate 进行批量更新

hibernate 批量操作saveOrUpdateAll

Hibernate批量处理数据HQL连接查询