当前位置: 首页 > news >正文

07. Hibernate 会话工厂(SessionFactory)

1. 前言

Hibernate 的核心价值观是:开发者们!做你们应该做的。脏的、累的、没技术含义的由本尊来做。

本节课和大家一起好好的聊聊 Hibernate 的核心组件之一:会话工厂(SessionFactory)。

通过本节课,你将学习到:

  • 会话工厂的设计要求;
  • 会话工厂的核心功能。

2. 会话工厂的作用

原生 Jdbc 开发如同自己炒菜做饭,需经手买菜、洗菜、做菜…… 一系列过程。

基于 Hibernate 框架开发类似找一家餐馆就餐,只需要坐在那里,订一份菜单,稍等便会有色相味俱全的菜品出现在面前。

餐馆并没有省略买菜、洗菜、做菜一系操作,对于顾客而言,这些由餐馆内部工作人员完成。

Hibernate 框架与此类似,原生 JDBC 开发的过程中一系列的标准流程一样也不能少,只是由内部组件替代完成

可把餐馆当成一个出品菜肴的工厂,为就餐者承担起一系列脏活、累活……

Hibernate 提供了一个 SessionFactory(会话工厂)对象,任劳任怨地为开发者承担起 Jdbc 开发流程中底层的繁琐事务操作。

2.1 概括会话工厂(SessionFactory)的功能

  • 为开发者屏蔽创建会话对象(session)时的一系列繁琐事宜,让开发者简单、直接获取 Session 对象,快速迭代自己的代码功能;
  • 可根据开发者在主配置文件中的配置需求,提供高级辅助功能(如数据库连接池……);
  • 会话工厂可缓存生成的 SQL 语句和 Hibernate 在运行时使用的映射元数据。

SessionFactory 类的设计顾名思议使用到工厂设计模式。经常会在一些框架程序中看到工厂设计模式,工厂设计模式的知名度如此之高,是由它自身的优势决定的:

  • 工厂对象替开发者完成创建对象的细枝末节,让开发者只需专注于如何运用对象;
  • 工厂对象内部可提供创建对象的优化方案,避免因开发者随意创建对象所带来的内存消耗。

古人打猎,需要用一周时间打磨工具,用一天时间捕捉猎物。现代人打猎前,可以去商店买一把猎枪,然后尽情享受打猎过程(保护野生动物,禁止打猎!)。

工厂设计模式对开发者说:享受开发吧!少年……

SessionFactory 从功能来讲似乎简单明了,创建 Session(其实这把猎枪不简单)。

2.2 会话工厂的使用细节

使用细节需要开发者了解:

  • SessionFactory 可看成对某一个具体数据库系统的抽象映射;
  • 项目不涉及多数据源时,整个应用程序只需要一个会话工厂,可在应用初始化时创建;
  • 多线程环境下,因 SessionFactory 需要在线程间共享,设计时考虑到了线程安全性问题,内部属性多使用 final 关键字修饰;
  • 如果使用 Hibernate 访问多个数据库,则需要对每一个数据库使用一个 SessionFactory。

综上所述:

  • 实用生产级别项目中,建议使用单例设计模式封装 SessionFactory 的创建,保证其应用程序作用域中的唯一性;
  • 尽量不要在封装类中使用全局实例变量存储数据,避开线程安全性问题。

3. 单例设计模式封装会话工厂的创建

测试环境是一个演示、求证过程,测试一次创建一个 SessionFactory 对象并没有什么不妥。

生产环境则不同,代码结构上设计如果有缺陷,或者不遵循对象本身的特性需求。产品上线后,可能会因为产品的设计缺陷给客户造成某种程度上的损失。

报酬拿不到事小,丢失市场信任事大。

使用 HibernateSessionFactory 对象封装 SessionFactory 的创建:

public class  HibernateSessionFactory {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  ServiceRegistryBuilder().applySettings(*configuration*.getProperties()).buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry);} catch (Exception e) {System.err.println("%%%%  Error Creating SessionFactory %%%%");e.printStackTrace(); } }    private  HibernateSessionFactory() {} public static Session  getSession() throws HibernateException {Session session = (Session) threadLocal.get();if (session == null || !session.isOpen()) {   session = (sessionFactory != null) ? sessionFactory.openSession():null;                   threadLocal.set(session);}  return session; }       public static void  closeSession() throws HibernateException {Session session = (Session) threadLocal.get();threadLocal.set(null);if (session != null) {session.close();} }      public static  org.hibernate.SessionFactory getSessionFactory() {return sessionFactory;} 
}  

HibernateSessionFactory 类内有很多代码值得细细品味,本节课你只需要关注单例设计模式实现要素:

  • 构造方法私有化,创建对象的能力由内部决定,阻止外部非法任意创建;
  private HibernateSessionFactory() {}
  • SessionFactory 在类的静态代码块内创建;
  private static  org.hibernate.SessionFactory sessionFactory;  //创建会话工厂,只会执行一次,也就只有一个对象static {//省略……}
  • 提供公开方法允许外部调用;
  public static org.hibernate.SessionFactory getSessionFactory() {//直接返回内部创建的会话工厂对象return sessionFactory;}

无论外部调用 getSessionFactory()方法多少次,最后创建的都只会有一个 SessionFactory 对象。

HibernateSessionFactory 类其它精华代码留到下一节课程。

4. 小结

工厂、工厂又见工厂!

工厂设计模式是一种屏蔽底层细节,为开发者创建高质量对象的优秀设计方案。怎么表扬这种设计模式都不为过。

到了本节课程说再见时刻,建议开发者,通过本节课程的学习,不仅要理解、掌握 Hibernate 中会话工厂的使用,更能把工厂模式很好地运用到自己的真实项目中。

既要学会使用 Hibernate,也要掌握其内在核心思想。

相关文章:

07. Hibernate 会话工厂(SessionFactory)

1. 前言 Hibernate 的核心价值观是&#xff1a;开发者们&#xff01;做你们应该做的。脏的、累的、没技术含义的由本尊来做。 本节课和大家一起好好的聊聊 Hibernate 的核心组件之一&#xff1a;会话工厂&#xff08;SessionFactory&#xff09;。 通过本节课&#xff0c;你…...

使用Nginx实现高效负载均衡

概述 Nginx是一款高性能的HTTP和反向代理服务器&#xff0c;广泛用于Web服务的负载均衡。它能有效分发流量至多个后端服务器&#xff0c;提高网站的可用性和响应速度&#xff0c;同时增强系统的可扩展性和安全性。本文将介绍如何配置Nginx进行负载均衡&#xff0c;并提供具体的…...

华为OD机考题(基础API)

基础API 字典排序 List<String> listnew ArrayList(); //add list member Arrays.sort(list);List<Map<String,Integer>> listnew ArrayList(); //add list member Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {Over…...

<数据集>UA-DETRAC车辆识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;20500张 标注数量(xml文件个数)&#xff1a;20500 标注数量(txt文件个数)&#xff1a;20500 标注类别数&#xff1a;4 标注类别名称&#xff1a;[car, van, others, bus] 序号类别名称图片数框数1car201871259342…...

学生管理系统(C语言)(Easy-x)

课 程 报 告 课 程 名 称&#xff1a; 程序设计实践 专 业 班 级 &#xff1a; XXXXX XXXXX 学 生 姓 名 &#xff1a; XXX 学 号 &#xff1a; 231040700302 任 课 教 师 &a…...

C# 解析省份、城市、区域 json文件

一、json文件内容如下&#xff0c;&#xff08;小程序里好像有用到...&#xff09;: 二、读取包含省份城市区域的json文件&#xff0c;并整理成想要的结果&#xff1a; string path Server.MapPath("/js"); string file System.IO.Path.Combine(path, "数据.…...

用C语言写的一个扫雷小游戏

头文件 调用头文件和声明函数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <time.h> #include <stdlib.h>#define ROW 9 #define COL 9#define ROWS ROW2 #define COLS COL2#define EASY_CONT 10//声明函数 //初始化棋盘函数 void InitB…...

C++——类和对象(初始化列表和运算符重载与静态与友元)

文章目录 初始化列表语法结构定义和使用案例初始化列表初始化常量成员&#xff1a; 注意事项 运算符重载加法运算符重载语法结构示例注意事项 减法运算符重载语法结构示例注意事项 等于运算符重载等于运算符 的重载语法示例注意事项 大于运算符重载大于运算符 > 的重载语法…...

【WPF】图片剪裁-ImageCropping

【WPF】图片剪裁-ImageCropping 背景技术栈实现思路核心代码界面布局Style处理逻辑使用技巧预览下载背景 机缘巧合吧,当时在全网寻找图像剪裁工具,但大都不能满足需求,于是决定动手写。当然如果只是为了完成这么一个功能就没有必要记录了,主要是不依赖与第三方图像库,且实…...

C++的模板(十二):forward模板

标准库的std::forward模板有一个类型T参数。在实际使用时&#xff0c;T取什么值应该不存在疑惑&#xff1a; class A { public:A() {}A(int n):n(n) {}template <class T> A(T &&a);void print(A &&a) { printf("A&&\n"); }void pri…...

docker desktop历史版本安装

1.安装choco Windows安装 choco包管理工具-CSDN博客 2.通过choco安装 下面例子为安装旧版2.3.0.2,其它版本类似 Chocolatey Software | Docker Desktop 2.3.0.2 https://download.docker.com/win/stable/45183/Docker%20Desktop%20Installer.exe choco install docker-des…...

Ubuntu系统成功安装Docker教程

服务器版本&#xff1a; Ubuntu 22.04.3 LTS 1. 卸载旧版本 Docker 的旧版本被称为 docker&#xff0c;docker.io 或 docker-engine 。如果已安装&#xff0c;需要卸载&#xff1a; sudo apt-get remove docker docker-engine docker.io containerd runc2. 更新 apt 软件包 …...

C++ 匹配并提取包括加中括号的日期时间的正则表达式

在C中&#xff0c;你可以使用std::regex库来匹配包含日期和时间的字符串。以下是一个简单的例子&#xff0c;它展示了如何使用正则表达式来匹配形如[YYYY-MM-DD HH:MM:SS]的字符串。include <iostream> #include <string> #include <regex> int main() { …...

一文-深入了解Ansible常见模块、安装和部署

1 Ansible 介绍 Ansible是一个配置管理系统configuration management system, python 语言是运维人员必须会的语言, ansible 是一个基于python 开发的&#xff08;集合了众多运维工具 puppet、cfengine、chef、func、fabric的优点&#xff09;自动化运维工具, 其功能实现基于ss…...

etcd的备份与恢复

一 为什么使用etcd 与ZooKeeper相比&#xff0c;etcd更简单&#xff0c;安装、部署和使用更加容易&#xff0c;并且etcd的某些功能是ZooKeeper所没有的。因此&#xff0c;在很多场景下&#xff0c;etcd 比ZooKeeper更受用户的青&#xff0c;具体表现在如下几个方面: 1 etcd更…...

从 Pandas 到 Polars 十八:数据科学 2025,对未来几年内数据科学领域发展的预测或展望

我在2021年底开始使用Polars和DuckDB。我立刻意识到这些库很快就会成为数据科学生态系统的核心。自那时起&#xff0c;这些库的受欢迎程度呈指数级增长。 在这篇文章中&#xff0c;我做出了一些关于未来几年数据科学领域的发展方向和原因的预测。 这篇文章旨在检验我的预测能力…...

【postgresql】pg_dump备份数据库

pg_dump 介绍 pg_dump 是一个用于备份 PostgreSQL 数据库的实用工具。它可以将数据库的内容导出为一个 SQL 脚本文件或其他格式的文件&#xff0c;以便在需要时进行恢复或迁移。 基本用法 pg_dump [选项] [数据库名] 命令选项 -h 或 --host&#xff1a;指定数据库服务器的主…...

服务器的80和443端口关闭也能申请SSL证书

一、简介 在服务器的80和443端口关闭的情况下&#xff0c;确实可以申请SSL证书&#xff0c;但申请过程和方法会根据证书类型和验证方式的不同而有所差异。 通常如果是网站域名申请SSL证书&#xff0c;哪怕服务器的80、443端口都打不开&#xff0c;也可以通过DNS解析的方式来验…...

Odoo17应用、模型、字段

新建最简应用 先启用开发人员模式。 新建一个没有菜单项的空壳应用(模块/插件)&#xff1a; 必须至少包含 2 个文件&#xff1a; __manifest__.py 文件和文件 __init__.py 。 该 __init__.py 文件目前可以保持为空&#xff0c;我们将在下一章中返回。另一方面&#xff0c;该…...

Airtest的控制手机滑动位置偏差修正方法总结

提起Airtest的控制手机滑动位置&#xff0c;就会想起swipe&#xff0c;因为这种方法比较常见&#xff0c;对于没有精度控制的朋友完全够用&#xff0c; 我现在遇到精度控制时&#xff0c;大家都觉得精度不够&#xff0c;现在我对滑动精度控制&#xff0c;找到比较好的方法&…...

LoRA训练助手实际作品集:50+真实图片描述→高质量英文Tag转化示例

LoRA训练助手实际作品集&#xff1a;50真实图片描述→高质量英文Tag转化示例 1. 工具简介与核心价值 LoRA训练助手是一个专门为AI绘画爱好者设计的智能标签生成工具。无论你是想要训练自己的Stable Diffusion模型&#xff0c;还是需要为FLUX模型准备训练数据&#xff0c;这个…...

告别代码噩梦:用Awesome-Dify-Workflow零代码30分钟实现企业级登录系统

告别代码噩梦&#xff1a;用Awesome-Dify-Workflow零代码30分钟实现企业级登录系统 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程&#xff0c;自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/…...

逆向工程必备:用aardio和Sunny中间件抓取手机App封包的3种实战姿势

逆向工程实战&#xff1a;aardio与Sunny中间件的移动端封包拦截艺术 在移动应用安全研究领域&#xff0c;封包拦截与分析是理解应用通信逻辑的关键入口。不同于传统的PC端抓包&#xff0c;移动环境面临着证书绑定、代理检测等更复杂的防御机制。aardio配合Sunny中间件构建的轻量…...

SystemVerilog进阶:深入探索随机化约束的高级应用

1. 从基础到进阶&#xff1a;SystemVerilog随机化约束的核心价值 在芯片验证领域&#xff0c;随机化验证已经成为提高验证效率的黄金标准。SystemVerilog的随机化约束机制&#xff0c;就像给验证工程师配备了一个智能数据生成器&#xff0c;可以自动产生符合设计规范的测试场景…...

UE5 RPG开发实战:用接口轻松搞定鼠标悬停敌人描边(含完整蓝图与C++代码)

UE5 RPG开发实战&#xff1a;用接口实现敌人悬停描边的高效方案 在动作角色扮演游戏&#xff08;ARPG&#xff09;开发中&#xff0c;清晰的交互反馈是提升玩家体验的关键环节。当玩家将鼠标悬停在敌人身上时&#xff0c;如何直观地标识当前选中的目标&#xff1f;本文将深入探…...

极客专属:OpenClaw+百川2-13B打造个人CLI智能助手

极客专属&#xff1a;OpenClaw百川2-13B打造个人CLI智能助手 1. 为什么开发者需要命令行智能助手 作为一个长期与终端打交道的开发者&#xff0c;我每天要重复执行大量机械操作&#xff1a;查看日志、运行测试、整理结果。这些工作虽然简单&#xff0c;却极其消耗精力。直到我…...

软件测试生命周期全解析:用考试答题逻辑,零基础吃透测试核心

之前我们用考场答题的类比&#xff0c;轻松搞懂了软件开发生命周期&#xff0c;很多初学者恍然大悟&#xff1a;原来编程就是一场有章法的“考试”。但一场考试能不能拿到高分、能不能符合出题人&#xff08;客户&#xff09;的要求&#xff0c;光靠埋头答题&#xff08;开发编…...

【人物传记】唯一一位两次获得诺贝尔物理学奖-约翰·巴

1 约翰巴丁简介 约翰巴丁&#xff08;英语&#xff1a;John Bardeen&#xff0c;1908年5月23日—1991年1月30日[6]&#xff09;是一名美国物理学家和工程师。他是唯一一个两度获得诺贝尔物理学奖的人&#xff1a;第一次是在1956年与威廉肖克利和沃尔特布拉顿一起发明晶体管&am…...

别再死记硬背公式了!Cesium中Entity姿态(HPR)的获取与设置,一个例子讲透

Cesium中Entity姿态控制的本质&#xff1a;从HPR到四元数的思维跃迁 当你第一次在Cesium中加载一个3D模型&#xff0c;却发现它头朝下或者背对镜头时&#xff0c;那种挫败感我深有体会。传统教程往往直接扔给你一堆转换公式&#xff0c;却很少解释为什么需要这些看似复杂的数学…...

Pycharm Database工具:一站式数据库可视化操作指南

1. 为什么你需要Pycharm Database工具&#xff1f; 如果你正在用Pycharm写Python代码&#xff0c;特别是开发Web应用时&#xff0c;很可能会遇到需要操作数据库的情况。很多开发者习惯在Pycharm和Navicat这样的独立数据库工具之间来回切换&#xff0c;这其实既浪费时间又影响开…...