上一节我们讲到了Hibernate的测试,并且给出了测试代码,刚开始看见这个测试代码的同学估计是一头雾水把,所以这一节我们来讲一下测试代码。

本节主要内容:

  • Configuration
  • SessionFactory
  • Session

首先我们再来看一下上一节的测试代码:

		//加载配置文件
Configuration config = new Configuration().configure();
//根据配置文件创建会话工厂
SessionFactory factory = config.buildSessionFactory();
//根据会话工厂创建会话
Session session = factory.getCurrentSession();
//创建一个事物对象
Transaction tx = session.beginTransaction();
//new 一个学生对象
Student student = new Student("小三‰",19,99);
//将对象持久化到数据表中
session.save(student);
//提交事务
tx.commit();
//关闭会话
session.close();
//关闭工厂
factory.close();

Configuration:

首先是Configuration,它是用来解析我们配置的一个类,它加载配置的时候使用了这段代码:

Configuration config = new Configuration().configure();

看到这段代码的第一感觉是为啥还要在后面加一个方法,直接new一个Configuration不就行了吗,为啥还加了一个configure方法。

我们来打开源码瞧瞧:

public Configuration configure() throws HibernateException {
return configure( StandardServiceRegistryBuilder.DEFAULT_CFG_RESOURCE_NAME );
}

看到了没,configure方法返回了一个有参的方法,且参数为:

StandardServiceRegistryBuilder.DEFAULT_CFG_RESOURCE_NAME

我们跟进去会发现这个参数是StandardServiceRegistryBuilder类定义的一个名字叫hibernate.config.xml的成员变量。

所以我们可以得出一个结论:如果你采用以下段代码来加载配置文件那么你的主配置文件名字必须叫作hibernate.config.xml

Configuration config = new Configuration().configure();

当然你也可以自定义,例如这样随意指定:

Configuration config = new Configuration().configure("xxx.xml');

但是我们建议使用hibernate指定的配置文件名。

这里我们只介绍这些,所以对于Configuration我们仅需要知道它是用来加载配置文件即可,以后具体分析,现在我们先将hibernate的基本原理讲明白就好。

SessionFactory:

SessionFactory factory = config.buildSessionFactory();

我们知道主配置文件里面最外面的便是<hibernate-configuration>接下来就是<session-factory>,所以通过Configuration实例对象的buildSessionFactory可以根据我们的配置文件建立会话工厂。值得注意的是SessionFactory是一个重量级的组件,是一个单例的,线程安全的。按理说单例对象一定是被共享的是线程不安全的,我们将它的实现类SessionFactoryimpl打开看发现它的大多数的成员变量都是final的,所以它是线程安全的。

一般SessionFactory实例都不进行关闭(开销太大),而是在应用结束的时候自动将其销毁。

Session:

session由SessionFactory的getCurrentSession()或者openSession()进行创建,在web应用中,每当有一个用户访问时就会为这个用户创建一个Session,所以Session是多例的,它包含了许多非final变量,对同一个用户可能会产生多个事务,若多事务同时对Session的同一个变量进行访问就会引起并发的问题从而导致线程不安全。

上面提到了Session的两种获取方式,接下来我们说一下两种方式的区别:

getCurrentSession无论执行多少次只要是在同一个线程中它获取到的都是同一个Session对象,使用这个方法获取的Session对象是由ThreadLocal变量存储的(ThreadLocal在我的多线程文章里面有介绍),它的底层是一个Map,key就为线程的名字,所以用这个方法创建的Session对象是线程唯一的。

它创建Session对象的时候会进行判断,判断线程是是否已经存在session,如果不存在便进行创建。以下便是它的实现源码(有源码有真相):

	public Session getCurrentSession() throws HibernateException {
if ( currentSessionContext == null ) {
throw new HibernateException( "No CurrentSessionContext configured!" );
}
return currentSessionContext.currentSession();
}

如果不存在那么久进行创建,底层也是通过openSession创建:

	protected Session buildOrObtainSession() {
return baseSessionBuilder()
.autoClose( isAutoCloseEnabled() )
.connectionReleaseMode( getConnectionReleaseMode() )
.flushBeforeCompletion( isAutoFlushEnabled() )
.openSession();//就是这里
}

具体的逻辑太多,不方便一直跟下去,所以有兴趣的可以一直跟下去。

openSession进行创建时,每执行一次便会创建一个Session对象,所以需要我们手动关闭,而getCurrentSession不用关闭。

getCurrentSession获得的Session对象不用注册便能够使用而openSession无需注册。

getCurrentSession获得的session对象一定要在事务里面执行,而openSession获得的对象可以不在事务里面执行。

以上就是对两种获取方式的简单总结。

Hibernate学习---Configuration,Session,SessionFactory的更多相关文章

  1. [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. Hibernate学习---用Session实现CURD

    我们使用Hibernate的目的是什么?对数据库进行操作,所有接下来我们就用Hibernate来进行CURD. 前边我们已经分析过了Configuration,SessionFactory和Sessi ...

  3. Hibernate学习三----------session详解

    © 版权声明:本文为博主原创文章,转载请注明出处 如何获取session对象 1. openSession 2. getCurrentSession - 如果使用getCurrentSession需要 ...

  4. Hibernate 的Configuration、sessionFactory和session和transaction对象解释

    1.Configuration对象: Configuration conf=new Configuration(); conf.configure(); 1.1 到 src下面找到名称hibernat ...

  5. [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. Hibernate二次学习二----------session.flush、session.doWork

    目录 1. session 2. session.flush 3. session.doWork 4. 完整代码 5. 总结 © 版权声明:本文为博主原创文章,转载请注明出处 1. session H ...

  8. Hibernate学习---第十四节:hibernate之session线程安全

    1.hibernate.cfg.xml 文件中添加如下代码开启线程安全: <property name="hibernate.current_session_context_class ...

  9. 【Hibernate学习笔记-3】在Spring下整合Hibernate时, 关于sessionFactory的类型的说明

    摘要 在Spring下整合Hibernate时,关于sessionFactory的配置方式主要有两种,分别为注解配置方式,和xml配置方式,下面将对这两种配置方式进行介绍. 1. sessionFac ...

随机推荐

  1. 如何管理Session(防止恶意共享账号)——理论篇

    目录 知识要求 背景 技术原理 如何管理Session remember me的问题 附录 知识要求 有一定的WEB后端开发基础,熟悉Session的用法,以及与Redis.Database的配合 本 ...

  2. Android 在通知栏实现计时功能

    Notification是APP 向系统发出通知时,它将先以图标的形式显示在通知栏中.用户可以下拉通知栏查看通知的详细信息.我们可以在通知栏实现自定义的效果,也可以结合service和BroadCas ...

  3. iOS 多线程之线程锁Swift-Demo示例总结

    线程锁是什么 在前面的文章中总结过多线程,总结了多线程之后,线程锁也是必须要好好总结的东西,这篇文章构思的时候可能写的东西得许多,只能挤时间一点点的慢慢的总结了,知道了线程之后要了解线程锁就得先了解一 ...

  4. C#设计模式之十八中介者模式(Mediator Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第五个模式,该模式是[中介者模式],英文名称是:Mediator Pattern.还是老套路,先从名字上来看看.“中介者模式”我第一次看到这个名称,我的理解 ...

  5. Java计算字符串中字母出现的次数

    话不多说,直接上代码........... public static void main(String[] args) { String str="I'm go to swimming&q ...

  6. 【二十二】mysqli事务处理

    事务处理 事务基本原理 如果不开启事务,执行一条sql,马上会持久化数据.可见:默认的mysql对sql语句的执行是自动提交的! 如果开启了事务,就是关闭了自动提交的功能,改成了commit执行自动提 ...

  7. openstack pike与ceph集成

    openstack pike与ceph集成 Ceph luminous 安装配置 http://www.cnblogs.com/elvi/p/7897178.html openstack pike 集 ...

  8. 【LintCode·入门】斐波那契数列

    斐波那契数列 描述 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, ...

  9. PHP入门怎么选?大学生适合学习吗?

    大学毕业,面对竞争激烈的社会,理想总是很丰满,现实却很残酷.在硕士.博士都随处可见的今天,本科和大专文凭就显得苍白无力,在面试官问你"有没有工作经验"的时候,你是不是只想起实习期间 ...

  10. video视频铺满

    1. 因项目需求,要在公司官网加一段视频,达到的效果是视频平铺整个网页,大小随网页变化:网上找了许久才找了了这么一个生僻的属性,只需给video加这么个样式就可以了:object-fit: fill; ...