【Hibernate框架】批量操作Batch总结

原创 2017年01月04日 11:33:33

       

       在我们做.net系统的时候,所做的最常见的批量操作就是批量导入、插入、更新、删除等等,以前我们怎么做呢?基本上有以下几种方式:

1、利用循环调用insert方法,一条条插入。

public boolean insertStudent(List<Student> studentList)
{
	try{
		if(studentList.count !=0){
			for(int i=0;i<studentList.count;i++){
				//调用save方法
			}
		        return true;
                }
	}catch(Exception ex){
		throw New Exception("插入失败,请重试!")
		return false;
	}
}



2、利用循环做sql语句拼接,然后批量执行sql语句。

public boolean insertStudent(List<Student> studentList)
{
	try{
		if(studentList.count !=0){
			stringBuffer strSqltxt="";
			for(int i=0;i<studentList.count;i++){
				strSqltxt.append("insert into TableName (……) values (……);"
			}
			cmd.executesql(strSqltxt.toString());
		}
	}catch(Exception ex){
		throw New Exception("插入失败,请重试!")
		return false;
	}
}


可是,对于封装比较完善的hibernate持久层,我们又能怎么做呢?

       

       最常见的,也是利用循环来批量操作,但是,这里有一个必须要注意的点,就是缓存或者说是session区的空间是有限的,禁不起我们无限制的存放,所以,当我们执行以下操作时,会抛异常,内存溢出OutOfMemoryException!

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
}
tx.commit();
session.close();

这样是不可以的,但是在这时,hibernate也给我们提供了解决方法,就是我们可以通过设置JDBC的批量抓去数量参数(batch size)来设置一个合适的值,比如说10-50-100不等,配置:

<property name="hibernate.jdbc.batch_size">100</property>


另外,我们还可以显示的禁用二级缓存,以前我们也提到过:

<property name="hibernate.cache.use_second_level_cache">false</property>


正确代码:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if(i%100==0){//100, 和配置的JDBC batch size一样
        session.fulsh();//刷出并同步到底层持久化, 批量的插入并且释放内存:
        session.clear(); //完全清除session
    }
}
tx.commit();
session.close();

这样就能解决我们的那个内存溢出的问题,因为当你的存储对象数超过你设定的能接受的合理值的时候,程序会自动将持久化对象flush进数据缓存起来,然后清空session,进行下一轮存储,待所有数据全部完成,执行commit进行提交,数据库更新数据,说的简单,这样的效率是不咋地的,不信你可以试试,你想想,先发出sql,100一轮,执行1000轮用来缓存sql语句,然后数据库统一执行sql,时间啊!


StatelessSession(无状态session)接口

但是这不是问题,因为hibernate还给我们提供了一个StatelessSession(无状态session)接口,作为选择,Hibernate提供了基于命令的API:

1、可以用detached object(托管对象)的形式把数据以流的方法加入到数据库,或从数据库输出。

2、StatelessSession没有持久化上下文,也不提供多少高层的生命周期语义。

3、无状态session不实现第一级cache;

4、也不和第二级缓存交互,也不和查询缓存交互。

5、它不实现事务化写,也不实现脏数据检查。

6、用stateless session进行的操作甚至不级联到关联实例。

7、stateless session忽略集合类(Collections)。

8、通过stateless session进行的操作不触发Hibernate的事件模型和拦截器。

9、无状态session对数据的混淆现象免疫,因为它没有第一级缓存。

10、无状态session是低层的抽象,和低层JDBC相当接近。换句话说,它可以直接操作数据

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
   
ScrollableResults customers = session.getNamedQuery("GetCustomers")
    .scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
    Customer customer = (Customer) customers.get(0);
    customer.updateStuff(...);
    session.update(customer);
}
   
tx.commit();
session.close();


DML(Data Manipulation Language数据操作语言)风格操作

再有就是特殊服务(业务需求)需要我们采用DML(Data Manipulation Language数据操作语言)风格操作,从一张表导入另一张表数据,比方说从学生表(T_Studeng)里面往大三学生表(T_ThreeStudent)里面倒数据.

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

String hqlInsert = "insert into ThreeStudent(id, name) select s.id, s.name from Student s where ...";
int createdEntities = s.createQuery( hqlInsert )
        .executeUpdate();
tx.commit();
session.close();


以上就是对批量操作的一点总结,万望对大家能有点帮助




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Hibernate 实现批量添加数据

Hibernate 实现批量添加数据 1.Hibernate_016_BatchAddData程序目录结构: 2.lib目录下所引入的jar包: 3.MedicineDa...

【java】itoo项目实战之hibernate 批量保存优化

在itoo中,基本上每个系统都有一个导入功能,大量的数据填写进入excel模板中,然后使用导入功能导入的数据库中,这样可以大大的提高工作效率。那么导入就涉及到了批量保存数据库的问题了。      那么...

hibernate 批量保存数据

一个完整的例子可以参照。 基本
  • agezhc
  • agezhc
  • 2014年05月08日 23:22
  • 961

浅谈Hibernate批量操作

在正式地介绍hibernate批量操作之前,先给大家普及一个hibernate重要的成员,即hibernate一级缓存,这个一级缓存不像二级缓存那样可插拔似的,是无条件使用的,这个缓存最大的一个作用就...

hibernate批量处理大数据

spring在管理hibernate上有独到的地方可以顺手拿来用,我也是想在能不抛弃hibernate的基础上尽可能多挖掘一下它的一些性能提升上的做法,总结大家的看法,基本得出一致结论:复杂查询依靠j...

四:Hibernate的批量操作

在Hibernate应用中,批量处理有两种方法,一种是通过Hibernate的缓存,另一种是绕过Hibernate,直接调用JDBC API来处理。 一:批量插入 (1)通过Hiberna...

Hibernate 数据的批量插入、更新和删除

4.2  Hibernate的批量处理Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象时,将被自动转换为对数据库的操作。例如调用Session的delete(...
  • gaozhlzh
  • gaozhlzh
  • 2011年06月23日 09:58
  • 38403

Hibernate批处理实战

我们在用数据库时,如果可以批量插入或者更新数据,可以很大地提高使用数据库的性能。但是我在用Hibernate实现批处理的过程中,走了一些弯路。下面我就把我的整个配置过程和经验总结分享,希望可以帮助到后...

Hibernate入门:批量插入数据

一般如果要插入100万条数据,则会写如下代码: package org.xiazdong.test; import junit.framework.TestCase; import or...
  • xiazdong
  • xiazdong
  • 2012年07月02日 17:20
  • 29301

Hibernate读书笔记-----hibernate的批量处理

Hibernate完全以面向对象的方式来操作数据库,当程序里以面向对象的方式操作持久化对象,将被自动转换为对数据库的操作。但存在这样一个问题,如果我们想同时更新100000条记录,是不是要逐一加载10...
  • chenssy
  • chenssy
  • 2012年07月06日 11:41
  • 4429
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【Hibernate框架】批量操作Batch总结
举报原因:
原因补充:

(最多只允许输入30个字)