Hibernate--管理Session

管理Session

在Hibernate的配置文件中,hibernate.current_session_context_class属性用于指定Session管理方式,可选值包括
1.thread:Session对象的生命周期与本地线程绑定
2.jta*:Session对象的生命周期与JTA事务绑定
3.managed:Hibernate委托程序来管理Session对象的生命周期

Session对象的生命周期与本地线程绑定

Hibernate按一下规则把Session与本地线程绑定
1)当一个线程(threadA)第一次调用SessionFactory对象的getCurrentSession()方法时,该方法会创建一个新的Session(sessionA)对象,把该对象与threadA绑定,并将sessionA返回
2)当threadA再次调用SessionFactory对象的getCurrentSession()方法时,该方法将返回sessionA对象
3)当threadA提交sessionA对象关联的事务时,Hibernate会自动flushsessionA对象的缓存,然后提交事务,关闭sessionA对象.当threadA撤销sessionA对象关联的事务时,也会自动关闭sessionA对象
4)若threadA再次调用SessionFactory对象的getCurrentSession()方法时,该方法会又创建一个新的Session(sessionB)对象,把该对象与threadA绑定,并将sessionB返回
示例代码:
在文件hibernate.cfg.xml中进行配置

<property name="current_session_context_class">thread</property>

代码:

public class HibernateUtils {
 private HibernateUtils() {}
 private static HibernateUtils instance=new HibernateUtils();
 public static HibernateUtils getInstance() {
  return instance;
 } 
 private SessionFactory sessionFactory;
 public SessionFactory getSessionFactory() {
  if(sessionFactory==null) {
   ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
   sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory(); 
  }
  return sessionFactory;
 }
 public Session getSession() {
  return getSessionFactory().getCurrentSession();
 }
}
public class DepartmentDao {
 public void save(Department dept) {
  Session session=HibernateUtils.getInstance().getSession();
  System.out.println(session.hashCode());
  session.save(dept);
 }
}
public void test() {
  Session session=HibernateUtils.getInstance().getSession();
  System.out.println("-->"+session.hashCode());
  Transaction transaction=session.beginTransaction();
  DepartmentDao departmentDao=new DepartmentDao();
  departmentDao.save(null);
  departmentDao.save(null);
  departmentDao.save(null);
  //若session是由thread来管理的,,则在提交或回滚事务时,已经关闭Session了。
  transaction.commit();
  System.out.println(session.isOpen());
 } 

Session对象的生命周期与JTA事务绑定

Hibernate委托程序管理Session对象的生命周期

批量处理数据

批量处理数据是指在一个事务中处理大量数据。

通过Session

通过Session来进行批量操作
1.Session的save()及update()方法都会把处理的对象存放在自己的缓存中.如果通过一个Session对象来处理大量持久化对象,应该及时从缓存中清空已经处理完毕并且不会再访问的对象.具体的做法是在处理完一个对象或小批量对象后,立即调用flush()方法刷新缓存,然后在调用clear()方法清空缓存
2.通过Session来进行处理操作会受到以下约束
1)需要在Hibernate配置文件中设置JDBC单次批量处理的数目,应保证每次向数据库发送的批量的SQL语句数目与batch_size属性一致
2)若对象采用“identity”标识符生成器,则Hibernate无法在JDBC层进行批量插入操作
3)进行批量操作时,建议关闭Hibernate的二级缓存
在这里插入图片描述
在进行批量更新时,如果一下子把所有对象都加载到Session缓存,然后再缓存中一一更新,显然是不可取的。
使用可滚动的结果集org.hibernate.ScrollableResults,该对象中实际上并不包含任何对象,只包含用于在线定位记录的游标.只有当程序遍历访问ScrollableResults对象的特定元素时,它才会到数据库中加载相应的对象.
在这里插入图片描述

通过HQL

注意: HQL 只支持 INSERT INTO … SELECT 形式的插入语句, 但不支持 INSERT INTO … VALUES 形式的插入语句. 所以使用 HQL 不能进行批量插入操作。

通过StatelessSession

StatelessSession与session相比,有以下区别:
1)StatelessSession没有缓存,通过StatelessSession来加载、保存或更新后的对象处于游离状态。
2)StatelessSession不会与Hibernate的第二级缓存交互。
3)当调用StatelessSession的save()、update()或delete()方法时,这些方法会立即执行相应的SQL语句,而不会仅计划执行一条SQL语句
4)StatelessSession不会进行脏检查,因此修改了Customer对象属性后,还需要调用StatelessSession的update()方法来更新数据库中数据。
5)StatelessSession不会对关联的对象进行任何级联操作。
6)通过同一个StatelessSession对象两次加载OID为1的Customer对象,得到的两个对象内存地址不同。
7)StatelessSession所做的操作可以被Interceptor拦截器捕获到,但是会被Hibernate的事件处理系统忽略掉。

通过JDBC API

public void testBatch() {
  session.doWork(new Work() {
   @Override
   public void execute(Connection connection) throws SQLException {
    //通过JDBC原生的API进行操作,效率最高,速度最快
   }
  });
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值