当前位置: 首页 > 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;找到比较好的方法&…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...