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

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;

	@Before
	public 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();
	}

	@After
	public void destroy(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	@Test
	public 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>

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

时间: 2024-12-15 07:16:03

hibernate 管理 Session(单独使用session,非spring)的相关文章

为什么要用Hibernate框架? 把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了?

既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢?把SessionFactory,Session,Transcational封装成包含crud的工具类并且处理了事务,那不是用不着spring了? Hibernate操作的步骤如下: 1. 获得Configuration对象 2. 创建SessionFactory 3. 创建Session 4. 打开事务 5. 进行持久化操作.比如上面的添加用户操作 6. 提交事务 7. 发生异常,回滚事务

Hibernate管理Session和批量操作

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

spring+hibernate管理多个数据源(非分布式事务)

本文通过一个demo,介绍如何使用spring+hibernate管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务. 这个demo将使用两个事务管理器分别管理两个数据源.对于每一个独立的事务,只涉及一个数据源. demo功能:实现一个能依靠两个独立的事务管理器互不干涉的管理自己的数据源的web demo. demo将实现: 1.独立地控制两个不同的数据源的事务管理器. 测试方式:restful web api 使用工具: spring 4.1.1.RELEASE hibernat

状态管理cookie和session

是由php提供的,session开关要放在代码最前面,session是保存在服务器的一般保存20分钟,cookie是保存在客户端的随便给值. 状态管理cookie和session,布布扣,bubuko.com

会话管理-2.1.Session介绍

1.Session是什么? 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上.这就是Session. 客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了,Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了. 2.Session的生命周期 Session在用户第一次访问服务器的时候自动创建.需要注意只有访问JSP.Servlet等程序时才会创建Session,只访问HTML.IMAGE等静态资源并不会创建S

hibernate中SessionFactory与Session的作用

首先,SessionFactory是线程安全的,SessionFactory用到了工厂模式. 其创建和销毁需要耗费很大的资源,所以一个应用中的一个数据库一般只对应一个sessionfactory. SessionFactory接口提供了获取session类实例的方法. 一般有两种方法创建session实例: 1.getCurrentSession方法: 采用该方法创建的session实例会绑定到当前线程当中.且session实例会在提交或回滚时自动关闭. 2.openSession方法: 采用该

spring管理的类如何调用非spring管理的类

spring管理的类如何调用非spring管理的类. 就是使用一个spring提供的感知概念,在容器启动的时候,注入上下文即可. 下面是一个工具类. 1 import org.springframework.beans.BeansException; 2 import org.springframework.context.ApplicationContext; 3 import org.springframework.context.ApplicationContextAware; 4 imp

2014-07-09 Java Web的学习(5)-----会话管理(Cookie和Session)

1.什么是会话 会话,牛津词典对其的解释是进行某活动连续的一段时间.从不同的层面看待会话,它有着类似但不全然相同的含义.比如,在web应用的用户看来,他打开浏览器访问一个电子商务网站,登录.并完成购物直到关闭浏览器,这是一个会话.而在web应用的开发者开来,用户登录时我需要创建一个数据结构以存储用户的登录信息,这个结构也叫做会话.因此在谈论会话的时候要注意上下文环境.而本文谈论的是一种基于HTTP协议的用以增强web应用能力的机制或者说一种方案,它不是单指某种特定的动态页面技术,而这种能力就是保

Java Web之会话管理二:Session

一.Session 在web开发中,服务器可以为每个yoghurt浏览器创建一个会话对象(Session)对象.注意:一个浏览器独占一个Session对象.因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其他程序时,其他程序可以从用户的seesion中取出该用户数据并为之服务 二.Session与Cookie的区别 Cookie是把用户的数据写给客户端 Session是把用户的数据写给用户独占的session中 Session对象由服