hibernate 管理 Session(单独使用session,非spring)

来源:互联网 发布:用js表示阶层 编辑:程序博客网 时间:2024/06/05 07:34

Hibernate 自身提供了三种管理 Session 对象的方法

  • Session 对象的生命周期与本地线程绑定
  • Session 对象的生命周期与 JTA 事务绑定
  • Hibernate 委托程序管理 Session 对象的生命周期

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


Session 对象的生命周期与本地线程绑定
如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session
Hibernate 按以下规则把 Session 与本地线程绑定
  • 当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回
  • 当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象
  • 当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动flush sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象
  • 若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadA 绑定, 并将 sessionB 返回



代码详解:
HibernateUtils.java(单例)
package com.atguigu.hibernate.hibernate;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;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) {Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);}return sessionFactory;}public Session getSession(){return getSessionFactory().getCurrentSession();}}

DepartmentDao.java
package com.atguigu.hibernate.dao;import org.hibernate.Session;import com.atguigu.hibernate.entities.Department;import com.atguigu.hibernate.hibernate.HibernateUtils;public class DepartmentDao {public void save(Department dept){//内部获取 Session 对象//获取和当前线程绑定的 Session 对象//1. 不需要从外部传入 Session 对象//2. 多个 DAO 方法也可以使用一个事务!Session session = HibernateUtils.getInstance().getSession();System.out.println(session.hashCode());session.save(dept);}/** * 若需要传入一个 Session 对象, 则意味着上一层(Service)需要获取到 Session 对象. * 这说明上一层需要和 Hibernate 的 API 紧密耦合. 所以不推荐使用此种方式.  */public void save(Session session, Department dept){session.save(dept);}}

Test
package com.atguigu.hibernate.test;import java.sql.Connection;import java.sql.SQLException;import java.util.ArrayList;import java.util.Arrays;import java.util.Iterator;import java.util.LinkedHashSet;import java.util.List;import org.hibernate.Criteria;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.criterion.Conjunction;import org.hibernate.criterion.Disjunction;import org.hibernate.criterion.MatchMode;import org.hibernate.criterion.Order;import org.hibernate.criterion.Projections;import org.hibernate.criterion.Restrictions;import org.hibernate.jdbc.Work;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.atguigu.hibernate.dao.DepartmentDao;import com.atguigu.hibernate.entities.Department;import com.atguigu.hibernate.entities.Employee;import com.atguigu.hibernate.hibernate.HibernateUtils;public class HibernateTest {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())                            .buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@Testpublic void testManageSession(){//获取 Session//开启事务Session session = HibernateUtils.getInstance().getSession();System.out.println("-->" + session.hashCode());Transaction transaction = session.beginTransaction();DepartmentDao departmentDao = new DepartmentDao();Department dept = new Department();dept.setName("ATGUIGU");departmentDao.save(dept);departmentDao.save(dept);departmentDao.save(dept);//若 Session 是由 thread 来管理的, 则在提交或回滚事务时, 已经关闭 Session 了. transaction.commit();System.out.println(session.isOpen()); }}

hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory>        <!-- Hibernate 连接数据库的基本信息 -->    <property name="connection.username">scott</property>    <property name="connection.password">java</property>    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>    <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property><!-- Hibernate 的基本配置 --><!-- Hibernate 使用的数据库方言 --><property name="dialect">org.hibernate.dialect.Oracle10gDialect</property><!-- 运行时是否打印 SQL -->    <property name="show_sql">true</property>        <!-- 运行时是否格式化 SQL -->    <property name="format_sql">true</property>        <!-- 生成数据表的策略 -->    <property name="hbm2ddl.auto">update</property>        <!-- 设置 Hibernate 的事务隔离级别 -->    <property name="connection.isolation">2</property>        <!-- 删除对象后, 使其 OID 置为 null -->    <property name="use_identifier_rollback">true</property>        <!-- 配置 C3P0 数据源 -->    <!--      <property name="hibernate.c3p0.max_size">10</property>    <property name="hibernate.c3p0.min_size">5</property>    <property name="c3p0.acquire_increment">2</property>        <property name="c3p0.idle_test_period">2000</property>    <property name="c3p0.timeout">2000</property>        <property name="c3p0.max_statements">10</property>    -->        <!-- 设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数 -->    <property name="hibernate.jdbc.fetch_size">100</property>        <!-- 设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小 -->    <property name="jdbc.batch_size">30</property>        <!-- 启用二级缓存 --><property name="cache.use_second_level_cache">true</property>        <!-- 配置使用的二级缓存的产品 -->    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>        <!-- 配置启用查询缓存 -->    <property name="cache.use_query_cache">true</property>        <!-- 配置管理 Session 的方式 -->    <property name="current_session_context_class">thread</property>        <!-- 需要关联的 hibernate 映射文件 .hbm.xml --><mapping resource="com/atguigu/hibernate/entities/Department.hbm.xml"/><mapping resource="com/atguigu/hibernate/entities/Employee.hbm.xml"/><class-cache usage="read-write" class="com.atguigu.hibernate.entities.Employee"/><class-cache usage="read-write" class="com.atguigu.hibernate.entities.Department"/><collection-cache usage="read-write" collection="com.atguigu.hibernate.entities.Department.emps"/>    </session-factory></hibernate-configuration>



0 0
原创粉丝点击