Hibernate是一个面向Java环境的ORM框架,用来把对象模型表示的对象映射到基于SQL的关系模型中去。通过Hibernate我们可以完全以面向对象的方式操作数据库,插入记录时只需实例化一个对象,然后调用Session对象的save方法。Hibernate会帮我们生成对应的sql语句,完成相应的插入操作。
例如我们想要将1000000条记录插入到数据库,通过Hibernate可能采用如下的做法:
Configuration conf = new Configuration().configure();
SessionFactory sf = conf.buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
for (int i = 0;i < 1000000;i ++){
User user = new User("n"+Integer.toString(i),(int)(Math.random()*100));
session.save(user);
}
tx.commit();
session.close();
sf.close();
运行程序后开始执行插入操作,但随着程序的运行,在某一时刻程序会运行失败,并且抛出OutOfMemoryException(内存溢出异常)。这是因为Hibernate的Session持有一个必选的一级缓存,所有的User实例都会在Session缓存区内进行缓存,当所有的save操作完成后再将所有User实例插入到数据库。但是内存空间是有限的,当批量插入的数据过多时,很有可能占满内存,抛出内存溢出异常。
解决这个问题方法很简单,只要定时将数据刷入数据库,不要等到所有数据都缓存到内存中。Hibernate的Session为我们提供了两个方法,一个是flush(),另一个是clear()。flush方法用来将当前缓存的数据插入到数据库,而clear可以将当前缓存的数据清除。更改后的代码如下:
Configuration conf = new Configuration().configure();
SessionFactory sf = conf.buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
for (int i = 0;i < 1000000;i ++){
User user = new User("n"+Integer.toString(i),(int)(Math.random()*100));
session.save(user);
if(i % 10000 == 0){
session.flush();
session.clear();
}
}
tx.commit();
session.close();
sf.close();
每10000个数据就插入一次数据库,这样一来就不会出现内存溢出异常了,1000000条数据就都可以插入到数据库了。