Hibernate管理Session和批量操作分析
本文详细分析了hibernate管理session和批量操作的用法。分享给大家供大家参考。具体分析如下:
hibernate管理session
hibernate自身提供了三种管理session对象的方法
① session对象的生命周期与本地线程绑定
② session对象的生命周期与jta事务绑定
③ hibernate委托程序管理session对象的生命周期
在hibernate的配置文件中,hibernate.current_session_context_class属性用于指定session管理方式,可选值包括:
① thread:session对象的生命周期与本地线程绑定
② jta*:session对象的生命周期与jta事务绑定
③ managed:hibernate委托程序来管理session对象的生命周期
session对象的生命周期与本地线程绑定:
如果把hibernate配置文件的hibernate.current_session_context_class属性值设置为thread,hibernate就会按照与本地线程绑定的方式来管理session
hibernate按以下规则把session与本地线程绑定:
当一个线程(thread)第一次调用sessionfactory对象的getcurrentsession()方法时,该方法会创建一个新的session(sessiona)对象,把该对象与threada绑定,并将session返回
当threada再次调用sessionfactory对象的getcurrentsession()方法时,该方法将返回sessiona对象
当threada提交sessiona对象关联的事务时,hibernate会自动flush sessiona对象的缓存,然后提交事务,关闭session随心。当threada撤销sessiona对象关联的事务时,也会自动关闭sessiona对象
若threada再次调用sessionfactory对象的getcurrentsession()方法时,该方法会又创建一个新的session(sessionb)对象,把该对象与threada绑定,并将sessionb返回
批量处理数据
批量处理数据是指在一个事务中处理大量数据
在应用层进程批量操作,主要有以下方式:
① 通过session
② 通过hql
③ 通过statelesssession
④ 通过jdbc api----推荐此种,因为速度最快
session进行批量操作:
session的save()及update()方法都会把处理的对象存放在自己的缓存中。如果通过一个session对象来处理大量持久化对象,应该及时从缓存中清空已经处理完毕并且不会再访问的对象。具体的做法是在处理完一个对象或小批量对象后,立即调用flush()方法刷新缓存,然后再调用clear()方法情况缓存
通过session来进行处理操作会受到以下约束:
需要在hibernate配置文件中设置jdbc单次批量处理的数目,应保证每次向数据库发送的批量的sql语句数目与batch size属性一致
若对象采用"identity"标识生成器,则hibernate无法在jdbc曾进行批量插入操作
进行批量操作时,建议关闭hibernate的二级缓存
批量插入数据代码演示:
for(int i = 0; i < 10000; i++) {
news = new news();
news.settitle("--" + i);
session.save(news);
if((i + 1) % 20 == 0) {
session.flush();
session.clear();
}
}
批量更新:在进行批量更新时,如果一下子把所有对象都加载到session缓存,然后再缓存中一一更新,显然是不可取的
使用可滚动的结果集org.hibernate.scrollableresults,该对象中实际上并不包含任何对象,只包含用于在线定位记录的游标。只有当程序遍历访问scrollableresults对象的特定元素时,它才会到数据库中加载相应的对象
org.hibernate.scrollableresults对象由query的scroll方法返回
通过hql进行批量操作:
注意:hql只支持insert into ... select形式的插入语句,但不支持insert into ... values形式的插入语句。所以使用hql不能进行批量插入操作
通过statelesssession进行批量操作:
从形式上看,statelesssession与session的用法类似。statelesssession与session相比,有以下区别:
statelesssession没有缓存,通过statelesssession来加载、保存或更新后的对象处于游离状态
statelesssession不会与hibernate的二级缓存交互
当调用statelesssession的save()、update()或delete()方法时,这些方法会立即执行相应的sql语句,而不会仅计划执行一条sql语句
statelesssession不会进行脏检查,因此修改了customer对象属性后,还需要调用statelesssession的update()方法来更新数据库中数据
statelesssession不会对关联的对象进行任何的级联操作
通过同一个statelesssession对象两次加载的oid为1的customer对象,得到的两个对象内存地址不同
statelesssession所做的操作可以被interceptor拦截器捕获到,但是会被hibernate的事件处理系统忽略掉
希望本文所述对大家的java程序设计有所帮助。
上一篇: python3之微信文章爬虫实例讲解