hibernate之openSession()和getCurrentSession()的区别

        这几天在学习hibernate的核心开发接口,了解到hibernate的session有两种获取方式,一种是通过Session session = sessionFactory.openSession()来获取,另外一种是通过Session session = sessionFactory.getCurrentSession()方法来获取,那么这两种方法有啥区别呢?

         首先OpenSession()是永远打开一个新的session,这个可以通过下面的方法来证明:        

	@Test
	public void test() {
		Student s =  new Student();
		StudentPK pk =  new StudentPK();
		s.setPk(pk);
		s.setAge(23);
		s.setClasses(1);
		pk.setId(1);
		pk.setName("moluo");
		
		Session session = sf.openSession();
		Session session1 = sf.openSession();
		session.beginTransaction();
		session.save(s);
		System.out.println(session == session1);   //输出结果为false;
		session.getTransaction().commit();
		session.close();
		session1.close();
	}
输出结果为false,显然这俩session不是同一个session,所以openSession()每次都是new一个新的session。        

         其次,OpenSession()打开一个session以后必须显式的去关闭(session.close())。

         再来看看getCurrentSession(),它是从上下文里找,如果有session,它就使用原来的session,如果没有它就new一个session。怎么证明呢?来看看下面这个例子:

@Test
	public void test() {
		Student s =  new Student();
		StudentPK pk =  new StudentPK();
		s.setPk(pk);
		s.setAge(23);
		s.setClasses(1);
		pk.setId(1);
		pk.setName("moluo");
		
		Session session = sf.getCurrentSession();
		Session session1 = sf.getCurrentSession();
		session.beginTransaction();
		session.save(s);
		System.out.println(session == session1);   //输出结果为true;
		session.getTransaction().commit();
		//session.close();
		//session1.close();
	}
输出结果为true,显然这俩session是同一个session,否则输出结果就是false了,也就是说当上下文如果存在一个session,它就使用原来的session。在事物没有提交或者回滚之前,无论我们拿多少次session,它们都是同一个session,但如果提交或者回滚了,再拿就是新的session了。

         另外,getCurrentSession()不需要我们显式的去关闭,因为当事物提交(session.getTransaction().commit())或者回滚之后,会自动的帮我们去关闭session。如果我们显式的去关闭session,就有可能会出现问题,所以不要去多此一举。

          既然提到了他俩都可以获取session,那么他俩获取到的session是否为同一个session呢?再看下面的例子:

	@Test
	public void test() {
		Student s =  new Student();
		StudentPK pk =  new StudentPK();
		s.setPk(pk);
		s.setAge(23);
		s.setClasses(1);
		pk.setId(1);
		pk.setName("moluo");
		
		Session session = sf.openSession();
		Session session1 = sf.getCurrentSession();
		session.beginTransaction();
		session.save(s);
		System.out.println(session == session1);   //输出结果为false;
		session.getTransaction().commit();
		//session.close();
	}
        输出结果为false,证明他俩不是同一个session,有些朋友就有可能会有疑问了,session1是通过getCurrentSession()得到的,而getCurrentSession()不是通过上下文获取session吗?上下文不是openSession(),不是已经有了一个session了吗?实际上session是一个接口,通过这俩方式得到的session的具体实现方式是不一样的,所以输出结果为false。

         讲到getCurrentSession()会从上下文里获取session,那么上下文的配置在哪呢?实际上在sf = new AnnotationConfiguration().configure().buildSessionFactory();这步就已经调用配置文件hibernate.cfg.xml了,如果配置文件不是这个默认名,而是hibernate.xml,那么就必须改成:

sf = new AnnotationConfiguration().configure(“hibernate.xml”).buildSessionFactory();也就是说在configure()方法就调用了配置文件。

          回归正题:上下文配置在配置文件的:

<property name="current_session_context_class">thread</property>
         这里一共有4个可选的参数,分别是:jta,thread,custom,managed。前两者比较常用,后两者很少用到。

         thread使用connection,用于单数据库连接事物管理,而jta(java transaction api)运行时需要application server提供支持,它主要用于多数据库,分布式事物管理,用于界定事物边界。

        另外,getCurrentSession()创建的session会绑定到当前线程中,而openSession()不会绑定。

         最后还有一点就是:openSession()可以在不开启事物的情况下执行,而getCurrentSession()不行。(这个是在网上看来的,未经佐证!)

尊重版权,转载请不要删除下方二维码并注明本文链接

                                 欢迎关注行者摩罗微信公众号(xingzhemoluo),共同交流编程经验,扫描下方二维码即可;

                                                        

         

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值