• 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();
  • 相关阅读:
    Java堆、栈和常量池
    Java多线程内存模型
    To-do List
    Java Collections Framework 汇总
    关于ArrayList.clear()与=null以及new ArrayList<E>()
    开源协议
    git-svn — 让git和svn协同工作
    Java Collections Framework 之 RandomAccess接口
    转 : CSS Modules详解及React中实践
    转 : JBoss Web和 Tomcat的区别
  • 原文地址:https://www.cnblogs.com/caoyc/p/5599975.html
Copyright © 2020-2023  润新知