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

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...