10 04Hibernate之HibernateSessionFactory
文章目录
- 1 ThreadLocal类的作用
- 2 HibernateSessionFactory分析
在使用MyEclipse创建Hibernate之后都会自动生成一个HibernateSessionFactory,这个类的主要功能是进行数据库连接对象(Session)的取得与关闭。
在以后的开发之中,很少会在代码里面去关注:Configuration、SessionFactory等操作。包括如何连接如何创建工厂都会被实际的其它操作所取代。用户最关注的就是如何进行数据的CRUD操作。
1 ThreadLocal类的作用
但是在这个HibernateSessionFactory里面有一个重要的操作实现:java.lang.ThreadLocal<T>
,这个类是一个帮助我们解决引用问题的操作类。这个类有如下两个重要的操作方法:
(1)设置对象内容:public void set(T value)
(2)取得对象内容:public T get()
下面通过一个实验来进行实际的使用分析。
范例:传统做法
package org.lks.test;public class News {private String title;
}
package org.lks.test;public class Message {public void print(News vo){System.out.println(vo.getTitle());}
}
传统的开发做法,是如果Message要想输出News类对象的内容,那么必须要在Message类里面传递一个News类对象的引用才可以进行处理。
范例:标准处理
package org.lks.test;public class TestMessage {public static void main(String[] args) {News vo = new News();vo.setTitle("hhy big fool");Message msg = new Message();msg.print(vo);}
}
整个代码使用了一个明确的对象引用操作的方式完成。
那么如果说此时使用的是ThreadLocal类,处理的形式就可以发生一些变化,不再需要由用户自己来处理明确的引用关系。
范例:定义ThreadUtil类,这个类主要负责传送ThreadLocal
package org.lks.test;public class ThreadUtil {private static ThreadLocal<News> threadLocal = new ThreadLocal<News>();public static ThreadLocal<News> getThreadLocal() {return threadLocal;}
}
范例:修改TestMessage的内容
package org.lks.test;public class TestMessage {public static void main(String[] args) {News vo = new News();vo.setTitle("hhy big fool");Message msg = new Message();ThreadUtil.getThreadLocal().set(vo);msg.print();}
}
此时没有必要再去处理引用关系,而直接利用ThreadLocal完成。
一般如果要在实际开发之中使用的话,往往用于数据库连接处理类的操作上。
2 HibernateSessionFactory分析
在MyEclipse里面为了简化开发提供有这样的工具类,这个工具类的主要目的是取得SessionFactory以及Session对象。现在最为重要的实际上是Session对象,所有的数据操作由此展开。
范例:分析HibernateSessionFactory
package org.lks.dbc;import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;/*** Configures and provides access to Hibernate sessions, tied to the* current thread of execution. Follows the Thread Local Session* pattern, see {@link http://hibernate.org/42.html }.*/
public class HibernateSessionFactory {/** * Location of hibernate.cfg.xml file.* Location should be on the classpath as Hibernate uses * #resourceAsStream style lookup for its configuration file. * The default classpath location of the hibernate config file is * in the default package. Use #setConfigFile() to update * the location of the configuration file for the current session. *///表示提供有ThreadLocal对象保存,适合于进行线程的准确处理private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();private static org.hibernate.SessionFactory sessionFactory; //连接工厂private static Configuration configuration = new Configuration(); //读取配置文件private static ServiceRegistry serviceRegistry; //服务注册类static { //静态代码块,可以在类加载的时候执行一次try {configuration.configure(); //读取配置文件serviceRegistry = new StandardServiceRegistryBuilder().configure().build();try {//在静态块中就已经准备好了SessionFactory类的对象sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();} catch (Exception e) {StandardServiceRegistryBuilder.destroy(serviceRegistry);e.printStackTrace();}} catch (Exception e) {System.err.println("%%%% Error Creating SessionFactory %%%%");e.printStackTrace();}}private HibernateSessionFactory() { //构造方法私有化,因为本类不需要提供构造}/*** Returns the ThreadLocal Session instance. Lazy initialize* the <code>SessionFactory</code> if needed.* * 取得Session对象,对象是通过ThreadLocal类取得的,如果没有保存的Session,那么会重新连接** @return Session操作对象* @throws HibernateException*/public static Session getSession() throws HibernateException {//为了防止用户可能重复使用Session对象,是通过保存在ThreadLocal类中的Session直接使用的Session session = (Session) threadLocal.get();if (session == null || !session.isOpen()) { //如果第一次使用或者之前关闭了,那么Session为nullif (sessionFactory == null) { //判断此时是否存在有SessionFactory类对象rebuildSessionFactory(); //如果SessionFactory不存在,则重新创建一个SessionFactory}//判断此时是否取得了SessionFactory类对象,如果取得,则使用openSession()打开新Session,否则返回nullsession = (sessionFactory != null) ? sessionFactory.openSession(): null;threadLocal.set(session); //为了防止可能重复使用Session,将其保存在ThreadLocal中。}return session;}/*** Rebuild hibernate session factory* * 重新进行SessionFactory类对象的创建**/public static void rebuildSessionFactory() {try {configuration.configure();serviceRegistry = new StandardServiceRegistryBuilder().configure().build();try {sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();} catch (Exception e) {StandardServiceRegistryBuilder.destroy(serviceRegistry);e.printStackTrace();}} catch (Exception e) {System.err.println("%%%% Error Creating SessionFactory %%%%");e.printStackTrace();}}/*** Close the single hibernate session instance.* * 所有操作的最后一定要关闭Session,在业务层中关闭** @throws HibernateException*/public static void closeSession() throws HibernateException {Session session = (Session) threadLocal.get(); //取得已有的Session对象threadLocal.set(null); //清空ThreadLocal的保存if (session != null) { //将Session进行关闭session.close();}}/*** return session factory* * 取得SessionFactory类的对象,目的是为了进行缓存操作**/public static org.hibernate.SessionFactory getSessionFactory() {return sessionFactory;}/*** return hibernate configuration* * 取得Configuration类的对象**/public static Configuration getConfiguration() {return configuration;}}
这个类只要使用就可以取得Session、SessionFactory、Configuration类的对象,至于如何取的,可以暂时不关心(因为Hibernate不可能单独使用,单独使用没有优势,都会结合到Spring上使用)。
范例:使用这个连接工厂类
package org.lks.test;import java.text.ParseException;
import java.text.SimpleDateFormat;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;public class TestMemberInsertDemoSimple {public static void main(String[] args) throws ParseException {// 1、设置VO的属性内容的操作应该由控制层完成Member pojo = new Member();pojo.setMid("31613012201");pojo.setMname("lks");pojo.setMage(23);pojo.setMsalary(2000.0);pojo.setMnote("hhy big fool!");pojo.setMbirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-10-15"));// 2、数据的保存操作应该由数据层完成HibernateSessionFactory.getSession().save(pojo);// 3、事务以及Session的关闭应该由业务层完成HibernateSessionFactory.getSession().beginTransaction().commit();HibernateSessionFactory.closeSession();}
}
以后在讲解Hibernate过程之中,就是用如上的操作方式。
10 04Hibernate之HibernateSessionFactory相关推荐
- Hibernate 双向一对一实现(基于annotation)
1.基于(foreign key)外键实现 国家<-------->首都 Country.java 1 package hibernate.orm.one2one.fk; 2 3 impo ...
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2
转自:https://blog.csdn.net/eson_15/article/details/51277324 今天开始做一个网上商城的项目,首先从搭建环境开始,一步步整合S2SH.这篇博文主要总 ...
- H3CNE最新版官网考试模拟题库
以下工作于OSI 参考模型数据链路层的设备是__A____.(选择一项或多项) A. 广域网交换机 B. 路由器 C. 中继器 D. 集线器 A 数据链路层传输的是帧,交换机是基于帧转发的:B 路由器 ...
- 10 20Hibernate之数据关联(多对多)
文章目录 1 基于`*.hbm.xml`文件的配置 2 基于Annotation的配置 多对多是一种在项目开发之中使用较多的操作情况,例如,在最为常见的管理员的权限处理过程之中,一定会存在有管理员的角 ...
- lisp协议instand_分享|Linux 上 10 个最好的 Markdown 编辑器
在这篇文章中,我们会点评一些可以在 Linux 上安装使用的最好的 Markdown 编辑器. 你可以在 Linux 平台上找到非常多的 的 Markdown 编辑器,但是在这里我们将尽可能地为您推荐 ...
- 10任务栏全屏时老是弹出_Deepin 15.10 发布,深度操作系统
深度操作系统是一个致力于为全球用户提供美观易用.安全可靠的Linux发行版. 深度操作系统基于Linux内核,以桌面应用为主的开源GNU/Linux操作系统,支持笔记本.台式机和一体机.深度操作系统( ...
- Linux shell 学习笔记(10)— 处理用户输入(命令行读取参数、读取用户输入、超时处理)
1. 命令行参数 向 shell 脚本传递数据的最基本方法是使用命令行参数.命令行参数允许在运行脚本时向命令行添加数据. $ ./addem 10 30 本例向脚本 addem 传递了两个命令行参数( ...
- Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建
Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建 一.Anaconda 创建 python3.7环境 1.进入 C:\Users\用户名 目录下,找到 ...
- debian 10 静态ip配置
查看网卡 ip addr 修改配置 vim /etc/network/interfaces 模板 auto ${网卡名} iface ${网卡名} inet ${static} address ${I ...
最新文章
- oracle之 如何 dump logfile
- 否认气候变暖的人都是睁眼说瞎话
- ubuntu18.04+语音识别
- 一分钟教程:注册谷歌邮箱
- 一元、二元函数图像绘制
- 计算机时区找不到北京,电脑时区里为何没有标准北京时间
- MongoDB SpringDataMongoDB 查询指南简介
- 大数据的分析技术,主要有哪些?
- 破解水卡教程 超详细
- 使用EXCEL计算并绘制MACD指标
- 国际赛事证书,220G数据集开放下载|ACCV2022国际细粒度图像分析挑战赛开赛
- QT-ico图片的生成
- 电脑android模拟器下载地址,原神电脑版怎么下载 安卓模拟器电脑版下载地址
- 台式电脑怎么锁定该计算机,教大家电脑整个键盘锁了怎么办
- cdoj1087 基爷的中位数 二分
- 保存PictureBox绘制的图像
- python竞赛试题及答案_python练习题答案
- 稻盛和夫:企业明天的希望寄托在每个人身上
- 你认为元宇宙是不是割韭菜?
- spark-shell计算某大学计算机系的成绩