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

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

  1. public boolean insertStudent(List<Student> studentList)
  2. {
  3. try{
  4. if(studentList.count !=0){
  5. for(int i=0;i<studentList.count;i++){
  6. //调用save方法
  7. }
  8. return true;
  9. }
  10. }catch(Exception ex){
  11. throw New Exception("插入失败,请重试!")
  12. return false;
  13. }
  14. }

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

  1. public boolean insertStudent(List<Student> studentList)
  2. {
  3. try{
  4. if(studentList.count !=0){
  5. stringBuffer strSqltxt="";
  6. for(int i=0;i<studentList.count;i++){
  7. strSqltxt.append("insert into TableName (……) values (……);"
  8. }
  9. cmd.executesql(strSqltxt.toString());
  10. }
  11. }catch(Exception ex){
  12. throw New Exception("插入失败,请重试!")
  13. return false;
  14. }
  15. }

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

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

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

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

  1. <span style="font-size:18px;"><property name="hibernate.jdbc.batch_size">100</property></span>

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

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

正确代码:

  1. Session session = sessionFactory.openSession();
  2. Transaction tx = session.beginTransaction();
  3. for ( int i=0; i<100000; i++ ) {
  4. Customer customer = new Customer(.....);
  5. session.save(customer);
  6. if(i%100==0){//100, 和配置的JDBC batch size一样
  7. session.fulsh();//刷出并同步到底层持久化, 批量的插入并且释放内存:
  8. session.clear(); //完全清除session
  9. }
  10. }
  11. tx.commit();
  12. 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相当接近。换句话说,它可以直接操作数据。

  1. StatelessSession session = sessionFactory.openStatelessSession();
  2. Transaction tx = session.beginTransaction();
  3. ScrollableResults customers = session.getNamedQuery("GetCustomers")
  4. .scroll(ScrollMode.FORWARD_ONLY);
  5. while ( customers.next() ) {
  6. Customer customer = (Customer) customers.get(0);
  7. customer.updateStuff(...);
  8. session.update(customer);
  9. }
  10. tx.commit();
  11. session.close();

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

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

  1. Session session = sessionFactory.openSession();
  2. Transaction tx = session.beginTransaction();
  3. String hqlInsert = "insert into ThreeStudent(id, name) select s.id, s.name from Student s where ...";
  4. int createdEntities = s.createQuery( hqlInsert )
  5. .executeUpdate();
  6. tx.commit();
  7. session.close();

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

【Hibernate框架】批量操作Batch总结的更多相关文章

  1. Hibernate框架(未完待续······)

        作为SSH三大框架之一的Hibernate,是用来把程序的Dao层和数据库打交道用的,它封装了JDBC的步骤,是我们对数据库的操作更加简单,更加快捷.利用Hibernate框架我们就可以不再编 ...

  2. Hibernate框架之Criteria查询 和注解(重点☆☆☆☆☆,难点☆☆☆)

    写好一篇博客,不是容易的事.原因是:你要给自己以后看的时候,还能看懂,最重要的是当别人看到你的博客文章的时候,也一样很清楚的明白你自己写的东西.其实这也是一种成就感!! 对于每一个知识点,要有必要的解 ...

  3. Hibernate 系列 01 - 框架技术 (介绍Hibernate框架的发展由来)

    引导目录: Hibernate 系列教程 目录 本篇导航: 为什么学习框架技术 框架的概念 主流框架的介绍 1.为什么学习框架技术 如何制作一份看上去具有专业水准的PPT文档呢?一个简单的方法就是使用 ...

  4. 2.0、Hibernate框架的简单搭建

    一.Hibernate:是一个开放源代码的对象关系映射框架,对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句 ...

  5. 【Hibernate框架】对象的三种持久化状态

    一.综述 hibernate中的对象有三种状态,分别是TransientObjects(瞬时对象).PersistentObjects(持久化对象)和DetachedObjects(托管对象也叫做离线 ...

  6. hibernate框架int和Integer类型区别

    hibernate 框架在定义实体时,int类型最好定义为Inttger类型,因为在注入时int是值类型不允许为空.

  7. SSH(Struts2+Spring+Hibernate)框架搭建流程<注解的方式创建Bean>

    此篇讲的是MyEclipse9工具提供的支持搭建自加包有代码也是相同:用户登录与注册的例子,表字段只有name,password. SSH,xml方式搭建文章链接地址:http://www.cnblo ...

  8. ECLIPSE/JAVAWEB (二)三大框架之Hibernate框架 持续更新中...

    (一)发展历史 在Struts框架中使用jdbc连接来读写数据库,我们最常见的就是打开数据库连接.使用复杂的sql语句进行读写.关闭连接,获得的数据又需要转换或封装后往外传,这是一个非常繁琐的过程. ...

  9. Hibernate框架简单应用

    Hibernate框架简单应用 Hibernate的核心组件在基于MVC设计模式的JAVA WEB应用中,Hibernate可以作为模型层/数据访问层.它通过配置文件(hibernate.proper ...

  10. Hibernate框架之get和load方法的区别

    我们在学习Hibernate框架时,经常会进行修改,删除操作,对于这些操作,我们都应该先加载对象,然后在执行或删除的操作,那么这里Hibernate提供了两种方法按照主键加载对象,也就是我要说的get ...

随机推荐

  1. javascript闭包

    关于闭包的介绍,推荐两篇文章: 廖雪峰javascript教程-闭包: http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a ...

  2. Linux 基础命令

    man      帮助命令   命令 --help   命令的简单帮助 help      命令的帮助(bash的内置命令) mkdir    创建目录  如makdir /data mkdir   ...

  3. easyUI中onLoadSuccess方法获取多个对象

    后台将一个list中的对象循环放到map中,如下: @RequestMapping("/getSaleOrderDetailList") @ResponseBody public ...

  4. 第3月第21天 nsclassfromstring返回null SVN报错:clean the working copy and then retry the operation

    1. xcodeproj工程损坏时,.m文件没有加入编译. 2. SVN报错:clean the working copy and then retry the operation http://bl ...

  5. 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  6. calendar的一些操作

    一.通过分析日期函数,根据日期进行一系列操作,例如:我们需要知道2个时间段中所有的日期等等. 由于Calendar 类是一个抽象类,因此我们不能通过new来获取该对象的实例.我们可以通过其类方法 ge ...

  7. MySQL 优化数据库对象

    一.考虑是用 procedure analyse() 函数对当前应用的表进行分析.字段类型是否可优化. 二.通过拆分提高表的访问效率. (A) 针对MyISAM表,有两种拆分方法: 垂直拆分:主码和某 ...

  8. _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)

    原文地址::http://blog.csdn.net/xiaolongwang2010/article/details/7550505 相关网帖 1.错误找不到WinsdkVer.h----http: ...

  9. C语言 完美字符串

    约翰认为字符串的完美度等于它里面所有字母的完美度之和.每个字母的完美度可以由你来分配,不同字母的完美度不同,分别对应一个1-26之间的整数. 约翰不在乎字母大小写.(也就是说字母F和f)的完美度相同. ...

  10. c#泛型的使用[转]

    在2005年底微软公司正式发布了C# 2.0,与C# 1.x相比,新版本增加了很多新特性,其中最重要的是对泛型的支持.通过泛型,我们可以定义类型安全的数据结构,而无需使用实际的数据类型.这能显著提高性 ...