Hibernate进阶篇(四)——session详解

来源:互联网 发布:js隐藏和显示div 编辑:程序博客网 时间:2024/05/21 06:44

转载请注明http://blog.csdn.net/uniquewonderq

首先看一下第一个问题:

如何获得session对象?

session对象是很重要的,hibernate操作数据库都是通过session 对象实现的,session对象表示数据库的一个连接。

那么获得session的方法有两种,

1.openSession()

2.getCurrentSession()

这两个方法都是来自于sessionFactory。

如果使用getCurrentSession()方法,需要在hibernate.cfg.xml文件中进行配置:

第一种:如果是本地事务(JDBC事务)

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

第二种:如果是全局事务(jta事务)

<property name="hibernate.current_session_context_class">jta</property>


下面经过第一个例子,说明第一种方法创建的过程(openSession()):

package test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.Test;public class SessionTest {@Testpublic void testOpenSession(){//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//获得session对象Session session=sessionFactory.openSession();if(session!=null){System.out.println("session创建成功!");}else{System.out.println("session创建失败!");}}

结果输出:session创建成功!


下面是第二种的(getCurrentSession()):

@Testpublic void testGetCurrentSession(){//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//获得session对象Session session=sessionFactory.getCurrentSession();if(session!=null){System.out.println("session创建成功!");}else{System.out.println("session创建失败!");}}

需要在hibernate.cfg.xml文件中进行配置:

本地事务(JDBC事务)

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

public void testGetCurrentSession(){//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//获得session对象Session session=sessionFactory.getCurrentSession();if(session!=null){System.out.println("session创建成功!");}else{System.out.println("session创建失败!");}}


输出结果:session创建成功!



openSession()和getCurrentSession()方法在创建session时候的区别:

1.通过getCurrentSession方法得到的session对象在事务提交或者回滚之后会自动关闭,而openSession需要你手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。

2.opensession每次创建新的session对象,getCurrentSession使用现有的session对象。(可以从英文字面看出来,一个是打开新的session,一个是得到现有的session)

通过一个例子我们来看看上面两点区别:

@Testpublic void testOpenSession(){//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//获得session对象Session session1=sessionFactory.openSession();Session session2=sessionFactory.openSession();System.out.println(session1==session2);//false}

结果输出:false

@Testpublic void testGetCurrentSession(){//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//获得session对象Session session1=sessionFactory.getCurrentSession();Session session2=sessionFactory.getCurrentSession();System.out.println(session1==session2);//true}

结果输出:true

测试代码2:可以根据两个创建的session的hashcode值来看是否是属于一个connection连接。

@Testpublic void testSaveStudentWithOpenSession(){//使用openSession来保存学生记录//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//创建session对象Session session1=sessionFactory.openSession();//开启事务Transaction transaction=session1.beginTransaction();//生成一个学生对象Students s=new Students(2,"花千骨","女",new Date(),"长留");session1.doWork(new Work() {@Overridepublic void execute(Connection connection) throws SQLException {System.out.println("connection hashCode: "+connection.hashCode());}});session1.save(s);//session1.close();不手动关闭transaction.commit();//提交事务Session session2=sessionFactory.openSession();transaction=session2.beginTransaction();s=new Students(3, "轻水","女", new Date(), "长留");session2.doWork(new Work() {@Overridepublic void execute(Connection connection) throws SQLException {System.out.println("connection hashCode: "+connection.hashCode());}});session2.save(s);transaction.commit();}


运行前的数据库:

运行后的数据库:


控制台输出:




上面也就验证了,如果没有释放session对象,那么这两个连接对象也就没有释放,那么越来越多的openSession 的话,迟早会有连接池异常的一天。


测试代码3:

public void testSaveStudentWithGetCurrentSession(){//使用getCurrentSession来保存学生记录//获得配置对象Configuration configuration=new Configuration().configure();//获得服务注册对象ServiceRegistry serviceRegistry=new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();//获得sessionFactory对象SessionFactory sessionFactory=configuration.buildSessionFactory(serviceRegistry);//创建session对象Session session=sessionFactory.getCurrentSession();//开启事务Transaction transaction=session.beginTransaction();//生成一个学生对象Students s=new Students(4,"白子画","男",new Date(),"长留");session.doWork(new Work() {@Overridepublic void execute(Connection connection) throws SQLException {System.out.println("connection hashCode: "+connection.hashCode());}});session.save(s);transaction.commit();//提交事务Session session2=sessionFactory.getCurrentSession();transaction=session2.beginTransaction();s=new Students(5, "赵丽颖","女", new Date(), "中国");session2.doWork(new Work() {@Overridepublic void execute(Connection connection) throws SQLException {System.out.println("connection hashCode: "+connection.hashCode());}});session2.save(s);transaction.commit();}

数据库结果:

控制台结果:



所以说,getCurrentSession方法每次会自动关闭session对象,那么虽然我们前后创建了两个session对象,但是,每次用完都释放了,然后connection对象在第一个释放后,就变得可用,而getCurrentSession方法本身获得当前的,当前的属于可用的。

综合,getConnection比较“节省”数据库连接池。在某些情况下,性能比较好。








0 0
原创粉丝点击