文章目录

  • 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相关推荐

  1. Hibernate 双向一对一实现(基于annotation)

    1.基于(foreign key)外键实现 国家<-------->首都 Country.java 1 package hibernate.orm.one2one.fk; 2 3 impo ...

  2. 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2

    转自:https://blog.csdn.net/eson_15/article/details/51277324 今天开始做一个网上商城的项目,首先从搭建环境开始,一步步整合S2SH.这篇博文主要总 ...

  3. H3CNE最新版官网考试模拟题库

    以下工作于OSI 参考模型数据链路层的设备是__A____.(选择一项或多项) A. 广域网交换机 B. 路由器 C. 中继器 D. 集线器 A 数据链路层传输的是帧,交换机是基于帧转发的:B 路由器 ...

  4. 10 20Hibernate之数据关联(多对多)

    文章目录 1 基于`*.hbm.xml`文件的配置 2 基于Annotation的配置 多对多是一种在项目开发之中使用较多的操作情况,例如,在最为常见的管理员的权限处理过程之中,一定会存在有管理员的角 ...

  5. lisp协议instand_分享|Linux 上 10 个最好的 Markdown 编辑器

    在这篇文章中,我们会点评一些可以在 Linux 上安装使用的最好的 Markdown 编辑器. 你可以在 Linux 平台上找到非常多的 的 Markdown 编辑器,但是在这里我们将尽可能地为您推荐 ...

  6. 10任务栏全屏时老是弹出_Deepin 15.10 发布,深度操作系统

    深度操作系统是一个致力于为全球用户提供美观易用.安全可靠的Linux发行版. 深度操作系统基于Linux内核,以桌面应用为主的开源GNU/Linux操作系统,支持笔记本.台式机和一体机.深度操作系统( ...

  7. Linux shell 学习笔记(10)— 处理用户输入(命令行读取参数、读取用户输入、超时处理)

    1. 命令行参数 向 shell 脚本传递数据的最基本方法是使用命令行参数.命令行参数允许在运行脚本时向命令行添加数据. $ ./addem 10 30 本例向脚本 addem 传递了两个命令行参数( ...

  8. Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建

    Anaconda3+python3.7.10+TensorFlow2.3.0+PyQt5环境搭建 一.Anaconda 创建 python3.7环境 1.进入 C:\Users\用户名 目录下,找到 ...

  9. debian 10 静态ip配置

    查看网卡 ip addr 修改配置 vim /etc/network/interfaces 模板 auto ${网卡名} iface ${网卡名} inet ${static} address ${I ...

最新文章

  1. XCode: 兼容ARC和non-ARC
  2. 如何读取FoxPro(dbf)打删除标记的记录
  3. 8.1.4 Authentication in a Web Application
  4. python数组用sum求和_对python中array.sum(axis=?)的用法介绍
  5. C#获取二叉树深度及分层遍历二叉树
  6. FastCGI中文规范
  7. 使用ssh tunnel 来做代理或跳板
  8. 应用id_科普贴:什么是OpenID、AppID 、用户ID等各种ID?
  9. 如何自定义已有架构的css样式
  10. C#调用存储过程,并且获得返回值和OutPut字符串
  11. 基于matlab的暴雨强度公式参数推求,基于MATLAB的暴雨强度公式参数推求
  12. PHP一句话木马,中国菜刀
  13. Echarts 三维地图
  14. 浅谈标签概念及应用场景
  15. MATLAB NAR时间序列神经网络两种预测方法
  16. 央视315曝光科技企业未击中痛点
  17. C语言类型限定符(type specifier)(一)——volatile详细教程
  18. 爱德华·琼斯(Edward Jones)公司
  19. Window管理右键菜单
  20. SAP SD基础知识之免费货物(Free Goods)

热门文章

  1. 使用js如何获取扩展名?
  2. python 中的@符号
  3. java抽象类介绍及代码
  4. 还是你厉害啊,用 Python 下载高清视频真速度
  5. 烽火运维-20180830day
  6. python打包上传至pypi —— 具有多个目录的项目工程快速打包上传
  7. 刷1000遍奥数题,不如学会这几道逻辑题,让孩子秒懂数学,学习早开窍!
  8. 新建数据库、附加数据库和添加表
  9. iOS swift5 UISlider 自定义UISlider 修改滑块和滑条的大小
  10. 步进电机———驱动器原理