Hibernate的sessionFactory获取session的方法有两种:
getCurrentSession()
openSession()
这两种方式有什么区别呢?
区别:
openSession()每次都开启一个session
openSession方法获得的session,在提交事务之后需要关闭session
getCurrentSession是从上下文中获取session,如果上下文中存在,就用上下文的。如果上下文中没有,就创建新的。
1. 用途,定义事务的边界
2. 事务提交自动关闭session,无需手动关闭
代码如下:
package cn.gduf.session;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.junit.Before;
import org.junit.Test;
/**
* Created by zhang on 2016/12/15.
*/
public class SessionTest {
private static Configuration configuration = null;
private static SessionFactory sessionFactory = null;
private static StandardServiceRegistryBuilder ssrb = null;
@Before
public void before() {
/**
* hibernate最新获取sessionFactory的方法,到stackoverflow才找到的,无力吐槽百度和国内论坛
*/
configuration = new Configuration().configure();
ssrb = new StandardServiceRegistryBuilder();
StandardServiceRegistryBuilder builder= ssrb.applySettings(
configuration.getProperties());
sessionFactory= configuration.buildSessionFactory(builder.build());
}
@Test
public void testSession1() {
Session session1 = sessionFactory.openSession();
Session session2 = sessionFactory.openSession();
System.out.println(session1 == session2);;
}
}
执行结果:
false
@Test
public void testSession2() {
Session session1 = sessionFactory.getCurrentSession();
Session session2 = sessionFactory.getCurrentSession();
System.out.println(session1 == session2);;
}
执行结果:
true
再来试下这个
@Test
public void testSession3() {
Session session1 = sessionFactory.getCurrentSession();
session1.getTransaction().begin();
session1.getTransaction().commit();
Session session2 = sessionFactory.getCurrentSession();
System.out.println(session1 == session2);;
}
这次结果是:
false
为什么呢?
因为第一次获取的session开启事务后提交了事务,session已经关闭了
第二次获取session时重新创建了一个session,所以两次获取的session会不一样
getCurrentSession提到的上下文指的是什么呢?
在hibernate的配置文件hibernate.cfg.xml中
进行如下设置
*如果使用的是本地事务(jdbc事务)
<propertyname="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)
<propertyname="hibernate.current_session_context_class">jta</property>
设置session上下文的取值
thred 指的是从当前线程中获取
jta(java transaction api)从全局事务中获取,适用于分布式数据库,比如说一个电商网站,商品的数目和信息在一个数据库上,消费金额在另一个数据库中,购买一件商品是一个事务,跨越了两个数据库,此时的session就不能从当前线程中获取了,需要从Transactionmanager管理的全局事务中获取。
Transactionmanager一般由应用服务器提供,tomcat目前不支持,但是可以结合spring来实现,jboss和weblogic是支持的。
一般在实际开发中都需要事务,所以getCurrentSession是推荐使用的。
接下来会提到spring整合hibernate的时候需要怎么管理事务