Hibernate学习---Configuration,Session,SessionFactory
上一节我们讲到了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的更多相关文章
- [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate学习---用Session实现CURD
我们使用Hibernate的目的是什么?对数据库进行操作,所有接下来我们就用Hibernate来进行CURD. 前边我们已经分析过了Configuration,SessionFactory和Sessi ...
- Hibernate学习三----------session详解
© 版权声明:本文为博主原创文章,转载请注明出处 如何获取session对象 1. openSession 2. getCurrentSession - 如果使用getCurrentSession需要 ...
- Hibernate 的Configuration、sessionFactory和session和transaction对象解释
1.Configuration对象: Configuration conf=new Configuration(); conf.configure(); 1.1 到 src下面找到名称hibernat ...
- [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate二次学习二----------session.flush、session.doWork
目录 1. session 2. session.flush 3. session.doWork 4. 完整代码 5. 总结 © 版权声明:本文为博主原创文章,转载请注明出处 1. session H ...
- Hibernate学习---第十四节:hibernate之session线程安全
1.hibernate.cfg.xml 文件中添加如下代码开启线程安全: <property name="hibernate.current_session_context_class ...
- 【Hibernate学习笔记-3】在Spring下整合Hibernate时, 关于sessionFactory的类型的说明
摘要 在Spring下整合Hibernate时,关于sessionFactory的配置方式主要有两种,分别为注解配置方式,和xml配置方式,下面将对这两种配置方式进行介绍. 1. sessionFac ...
随机推荐
- 深入理解Postgres中的cache
众所周知,缓存是提高数据库性能的一个重要手段.本文着重讲一讲PostgreSQL中的缓存相关的东西.当然万变不离其宗,原理都是共同的,理解了这些,你也很容易把它运用到其它数据库中. What is a ...
- 关于node的前端项目编译时内存溢出问题
最近在做一个基于vue 的多页面项目 , 页面n++多,编译时发生node内存溢出问题,继而百度之,得到解答,故记录之. '如图' 只需在 package.json 里面 加上 --max ...
- css3实现聊天气泡
1: <div class="comment"></div><style type="text/css"> .comment ...
- JAVAFX-3 开发应用
理解布局 布局容器(Layoutcontainer)或面板(Pane)允许对JavaFX应用程序场景图中的UI控件进行灵活.动态的排布.JavaFX Layout API包括下列容器类: ● Bord ...
- Less注释语法
Less注释语法 适当的注释是保证代码可读性的必要手段,Less支持两种类型的注释:多行注释和单行注释. 1)形如 /* */ 的多行注释.如: /* Hello, I'm a CSS-style c ...
- C语言之++--
#include<stdio.h>int main(){int num,count=0,i=0;scanf("%d",&num);printf("nu ...
- sqlserver的四种分页方式
第一种:ROW_NUMBER() OVER()方式 select * from ( select *, ROW_NUMBER() OVER(Order by ArtistId ) AS RowId f ...
- PHP设置环境变量
如果提示php命令不存在.说明未设置.设置方法如下 方法一:直接运行命令 [PHP] 纯文本查看 复制代码 ? 1 export PATH=$PATH:/usr/local/xxxx/php/bin ...
- How to get table pg_stat_user_functions.
修改配置文件postgres.conf track_functions = all # none, pl, all 或者 在当前事物中设置 postgres=# s ...
- keepalived结合nginx实现nginx高可用
1.简介 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台 ...