hibernate执行流程

hebernate session一直不关闭 hibernate session connection_session


首先要创建一个配置对象Configuration,配置对象的作用就是来读取我们的配置文档。

获得这个配置对象的目的就是可以用它来创建SessionFactory对象,创建这个对象可以读取相应的里边加载的对象-关系映射文件。

获得了SessionFactory对象之后就可以创建Session对象,类似于JDBC中的Connection,获得了一个Session对象就相当于获得了一个数据库连接对象,就可以执行Session对象相应的方法。

要执行某一个Session对象的方法的时候要开启一个事务,也就是说这些方法都要封装在事务中。执行完方法之后要先提交事务再关闭Session。

session简介

hibernate是对jdbc的一个封装,所以不建议直接使用jdbc的connection操作数据库,而是通过使用session对象操作数据库。
这里可以简单的理解为session就是一个操作数据库的对象。那么在使用hibernate操作数据库之前就必须要先获得一个session实例。
session和jdbc connection是多对一的关系,每个session都有一个与之对应的connection对象,一个connection不同时刻可以供多个session使用。
要把对象保存在关系数据库中需要调用session的各种方法
如:save()、update()、delete()、createQuery()等。

transaction简介

hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式。所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。
如果想让hibernate像jdbc那样自动提交事务,必须调用session对象的doWork()方法,获得jdbc的connection后,设值其为自动提交事务模式(注意:通常并不推荐这样做)。

在之前例子中

public class StudentsTest {

    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;

    @Before
    public void init(){
        //创建配置对象
        Configuration config = new Configuration().configure();
        //创建服务注册对象
        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
        //创建会话工厂对象
        sessionFactory = config.buildSessionFactory(serviceRegistry);
        //创建会话对象
        session = sessionFactory.openSession();
        //开启事务
        transaction = session.beginTransaction();
    }

    @After
    public void destory(){

        transaction.commit();//提交事务
        session.close();//关闭会话
        sessionFactory.close();//关闭会话工厂
    }

    @Test
    public void testSaveStudents(){
        //生产学生对象
        Students s = new Students(1,"张三丰","男",new Date(),"武当山");
        session.save(s);//保存对象进入数据库
    }
}

在init方法中有transaction = session.beginTransaction();开启事务
在destroy方法中有transaction.commit();提交事务
若没有的话就无法将对象保存到数据库中

把这两句注释掉
在test方法中药按照如下写法:

@Test
public void testSaveStudents(){
    //生产学生对象
    Students s = new Students(1,"张三丰","男",new Date(),"武当山");

    session.doWork(new Work(){
        @Override
        public void execute(Connection connection)throws SQLException{
            connection.setAutoCommit(true);
        }
    });

    session.save(s);//保存对象进入数据库
    session.flush();
}

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>

第一种方法就是之前的例子中的Session session = sessionFactory.openSession();
第二种方法只是将方法名改了并且在hibernate.cfg.xml文件中加了一个配置
Session session = sessionFactory.getCurrentSession();

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

openSession与getCurrentSession的区别
1.getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession需要手动关闭。如果使用openSession而没有手动关闭,多次之后会导致连接池溢出。
2.openSession每次创建新的session对象,getCurrentSession使用现有的session对象(单例)。