Hibernate批量处理

(一)   认识批量处理

代码

Session session=sessionFactory.openSession();

Transaction transaction = session.beginTransaction();

for(int i=0;i<100000;i++){

 

         Customer customer = new Customer(...);

         session.save(customer);

}

tx.commit();

session.close();

运行的现象:

         大概在50000条数据的时候,程序会出现异常,内存溢出异常OutOfMemoryException

原因:

         Hibernate把所有的新插入的客户实例在session级别的缓存区进行缓存的缘故。

解决方案:

  • 批量抓取
    •   hibernate.jdbc.batch_size 20
  • 关闭二级缓存
    •   hibernate.cache.use_second_level_cache flase

(二)   批量插入

合理的方案:

         如果要将很多对象持久化,必须经常调用flush()以及稍后调用clear()来控制一级缓存的大小。

代码演示

         public class UserManager

{

         public staitc void main(String []args){

                   UserManager userManager = new UserManager();

                   userManager.addUsers();

                            HibernateUtil.sessionFactory.close();

         }

         public void addUsers() throws Exception{{

                   Session session = HiernateUtil.currentSession();

                   Transaction transaction = session.beginTransaction();

                   //循环100000次,插入100000条记录

                   for(int i=0;i<100000;i++){

                            User user = new User();

                            user.setName....

                            session.save(user);

                            //每当累加器是20的倍数的时候,将session中的数据刷入到数据库中

                            if(i%20 == 0){

                                     session.flush();

                                     session.clear();

                            }

                  

                   }

                   transaction.close();

                   HibernateUtil.closeSession();

         }

}

注意不但需要处理session的缓存,还需要关闭sessionFactory的二级缓存。

 

(三)   批量更新

在进行会返回多行数据的查询的时候,需要使用方法scroll()利用服务器游标所带来的的好处。

代码演示

Sessionsession = sessionFactory.openSession();

Transaction transaction = sessionFactory.beginTransaction();

 

ScrollableResults customers = session.getNameQuery("GetCustomers").setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);

int count = 0;

while(customers.next()){

         Customer customer = (Customer)customers.get(0);

         customer.updateStuff(...);

         if(count++ == 0){

                   //flush a batch of updates and relase memory

                   session.flush();

                   session.clear();

         }

}

缺点:

         这种方式执行更新效率不高,hibernate需要查询一条语句然后再更新一条语句,为了避免这种性能低下的情形,Hibernate提供了一种类似于DML语句的批量更新。

 

(四)   StatelessSession(无状态会话)接口

思想:

Hibernatei提供了基于命令的API,可以用detached object的形式把数据以流的方法加入到数据库,或者从数据库中取出

StatelessSession的特点

  • 没有持久化的上下文
  • 不实现第一级cache也不与第二级缓存交互
  • 不实现事务化也不实现脏数据检查
  • 通过StatelessSession得到的实例会立即脱管,与任何持久化上下文都没有关系

  什么是脏数据?脏数据并不是废弃和无用的数据,而是状态前后发生变化的数据。我们看下面的代码:

 Transaction tx=session.beginTransaction();

 User user=(User)session.load(User.class,”1”);//从数据库中加载符合条件的数据

 user.setName(“zx”);//改变了user对象的姓名属性,此时user对象成为了所谓的“脏数据”

 tx.commit();

接口StatelessSession定义的insert,update,delete操作时直接数据库的级别操作,与session有很大的不同。

  

 

posted on 2014-10-16 16:03  六水先生  阅读(385)  评论(0编辑  收藏  举报