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

MyBatis SqlSession 是如何创建的? 它与 SqlSessionFactory 有什么关系?

SqlSession 是 MyBatis 中与数据库交互的核心接口,它提供了执行 SQL 语句、管理事务、获取 Mapper 接口代理对象等关键功能。 SqlSession 实例 不是直接通过 new 关键字创建的,而是通过 SqlSessionFactory 工厂来创建的。 SqlSessionFactory 负责创建 SqlSession 实例,并管理 SqlSession 的生命周期。

1. SqlSession 的创建方式:通过 SqlSessionFactory 工厂

SqlSession 的创建完全依赖于 SqlSessionFactory 工厂。 SqlSessionFactory 接口提供了多个 openSession() 方法的重载版本,用于创建不同类型的 SqlSession 实例。 最常用的创建 SqlSession 的方式是通过 SqlSessionFactory.openSession() 方法。

常见的 SqlSessionFactory.openSession() 方法调用方式:

  • SqlSession openSession() (最常用):

    SqlSessionFactory sqlSessionFactory = ...; // 假设已经创建了 SqlSessionFactory 实例
    SqlSession sqlSession = sqlSessionFactory.openSession(); // 创建一个新的 SqlSession 实例
    
    • 这是最常用的方式,创建一个默认配置的 SqlSession 实例
    • 默认情况下,SqlSession 实例不会自动提交事务 (autoCommit = false)。 需要手动调用 sqlSession.commit() 提交事务,或 sqlSession.rollback() 回滚事务。
    • 默认情况下,SqlSession 使用 ExecutorType.SIMPLE 执行器。
  • SqlSession openSession(boolean autoCommit):

    SqlSession sqlSession = sqlSessionFactory.openSession(true); // 创建一个自动提交事务的 SqlSession 实例
    
    • 创建一个 SqlSession 实例,并 设置事务是否自动提交
    • autoCommit = true: SqlSession 会自动提交事务。 每次执行 SQL 语句后,事务会自动提交。 适用于不需要手动控制事务的简单场景。
    • autoCommit = false: SqlSession 不会自动提交事务 (默认值)。 需要手动调用 sqlSession.commit()sqlSession.rollback() 来管理事务。 适用于需要手动控制事务边界的场景。
  • SqlSession openSession(ExecutorType executorType):

    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); // 创建一个使用 BATCH 执行器的 SqlSession 实例
    
    • 创建一个 SqlSession 实例,并 指定使用的执行器类型 (ExecutorType)
    • ExecutorType 是一个枚举,定义了 MyBatis 执行 SQL 语句的不同执行器类型:
      • ExecutorType.SIMPLE (默认): 简单执行器。 每次执行 SQL 语句都会创建一个新的 Statement 对象。 性能相对较低,但实现简单。
      • ExecutorType.REUSE: 复用执行器。 复用 Statement 对象。 如果执行相同的 SQL 语句 (只是参数不同),可以复用 Statement 对象,提高性能。
      • ExecutorType.BATCH: 批量执行器。 支持批量执行 SQL 语句,可以显著提高批量操作的性能。 适用于批量插入、批量更新等场景。
  • SqlSession openSession(TransactionIsolationLevel level) (已过时):

    // @Deprecated in MyBatis 3.5.x and removed in MyBatis 3.6.x
    // SqlSession sqlSession = sqlSessionFactory.openSession(TransactionIsolationLevel.READ_COMMITTED);
    
    • 已过时 (Deprecated) 且已移除: 在 MyBatis 3.5.x 中被标记为过时,并在 MyBatis 3.6.x 中被移除。 不再推荐使用此方法,事务隔离级别应该在数据源连接池或事务管理器中配置。
  • SqlSession openSession(ExecutorType executorType, boolean autoCommit):

    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE, true); // 创建一个使用 REUSE 执行器并自动提交事务的 SqlSession 实例
    
    • 创建一个 SqlSession 实例,同时指定执行器类型和是否自动提交事务
    • 结合了 openSession(ExecutorType executorType)openSession(boolean autoCommit) 两个方法的参数。
  • SqlSession openSession(Connection connection):

    Connection connection = ...; // 假设已经获取了 JDBC Connection 对象 (例如从数据源)
    SqlSession sqlSession = sqlSessionFactory.openSession(connection); // 使用已有的 Connection 对象创建 SqlSession 实例
    
    • 创建一个 SqlSession 实例,并 使用已有的 JDBC Connection 对象
    • 适用于需要 复用外部事务管理 的场景,例如在 Spring 事务管理下,Spring 会提供 Connection 对象,MyBatis 可以复用 Spring 管理的 Connection 和事务。
    • 使用此方法创建的 SqlSession 不会从数据源获取新的连接,而是直接使用传入的 Connection 对象。 SqlSession 也不会负责关闭传入的 Connection 对象,连接的关闭责任由外部调用者承担。
  • SqlSession openSession(ExecutorType executorType, TransactionIsolationLevel level) (已过时):

    // @Deprecated in MyBatis 3.5.x and removed in MyBatis 3.6.x
    // SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, TransactionIsolationLevel.SERIALIZABLE);
    
    • 已过时 (Deprecated) 且已移除: 同样被标记为过时并移除,不推荐使用。
  • SqlSession openSession(ExecutorType executorType, Connection connection):

    Connection connection = ...;
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, connection); // 创建一个使用 BATCH 执行器并使用已有 Connection 的 SqlSession 实例
    
    • 创建一个 SqlSession 实例,同时指定执行器类型和使用已有的 JDBC Connection 对象
    • 结合了 openSession(ExecutorType executorType)openSession(Connection connection) 两个方法的参数。
  • SqlSession openSession(ExecutorType executorType, boolean autoCommit, TransactionIsolationLevel level) (已过时):

    // @Deprecated in MyBatis 3.5.x and removed in MyBatis 3.6.x
    // SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE, true, TransactionIsolationLevel.REPEATABLE_READ);
    
    • 已过时 (Deprecated) 且已移除: 同样被标记为过时并移除,不推荐使用。

2. SqlSessionSqlSessionFactory 的关系:工厂和产品

SqlSessionSqlSessionFactory 之间是典型的 工厂模式 (Factory Pattern) 的关系:

  • SqlSessionFactory 是工厂 (Factory):

    • SqlSessionFactory 接口及其实现类 (通常是 DefaultSqlSessionFactory) 充当 工厂 的角色。
    • SqlSessionFactory 的职责是创建和管理 SqlSession 实例。 它负责创建 SqlSession 对象,并为 SqlSession 提供必要的配置信息 (例如 Configuration 对象)。
    • SqlSessionFactory 是一个 重量级对象,创建过程相对耗时,但在应用的整个生命周期中,通常 只需要创建一个 SqlSessionFactory 实例 (单例)
  • SqlSession 是产品 (Product):

    • SqlSession 接口及其实现类 (通常是 DefaultSqlSession) 充当 产品 的角色。
    • SqlSession 是 MyBatis 与数据库交互的主要接口。 开发者通过 SqlSession 执行 SQL 语句、管理事务、获取 Mapper 接口代理对象等。
    • SqlSession 是一个 轻量级对象,创建速度快。 但 SqlSession 不是线程安全的。 最佳实践是 在每个线程中获取一个新的 SqlSession 实例,并在使用完成后及时关闭 (sqlSession.close())。 通常,SqlSession 的生命周期应该 尽可能短 (Request-Scoped)

关系总结:

  • SqlSessionFactorySqlSession 的工厂,负责创建 SqlSession 实例。
  • SqlSessionFactory 是单例的 (Singleton),在应用生命周期内通常只有一个实例。
  • SqlSession 是非线程安全的,轻量级的,通常是请求作用域 (Request-Scoped) 的,每次数据库操作都应该获取新的 SqlSession 实例。
  • SqlSessionFactory 内部持有 Configuration 对象,SqlSessionSqlSessionFactory 获取 Configuration 信息,并使用 Configuration 进行 SQL 执行、结果映射等操作.

简单比喻:

你可以将 SqlSessionFactory 比喻成一个 汽车工厂,而 SqlSession 比喻成 工厂生产的汽车

  • 汽车工厂 (SqlSessionFactory): 负责生产汽车 (SqlSession)。 工厂本身很大,建造工厂成本很高 (创建 SqlSessionFactory 耗时),但工厂可以持续生产汽车。
  • 汽车 (SqlSession): 工厂生产的产品,用于实际的驾驶 (数据库操作)。 汽车相对轻便,容易生产 (创建 SqlSession 速度快),但汽车是消耗品,需要定期维护和更换 ( SqlSession 不是线程安全的,需要短生命周期)。

3. SqlSession 的生命周期和使用:

  • 获取 SqlSession: 通过 SqlSessionFactory.openSession() 方法获取 SqlSession 实例。
  • 执行数据库操作: 使用 SqlSession 提供的各种方法 (例如 selectOne(), selectList(), insert(), update(), delete(), getMapper() 等) 执行 SQL 语句或获取 Mapper 接口代理对象。
  • 管理事务 (如果 autoCommit = false):
    • sqlSession.commit(): 提交事务。
    • sqlSession.rollback(): 回滚事务。
  • 关闭 SqlSession: 务必在使用完成后及时关闭 SqlSession (sqlSession.close()). close() 方法会释放 SqlSession 占用的资源 (例如 JDBC 连接),并将其归还给连接池 (如果使用了连接池数据源)。 不及时关闭 SqlSession 会导致资源泄漏,影响系统性能和稳定性。 通常在 finally 块中关闭 SqlSession,确保无论是否发生异常,SqlSession 都能被正确关闭。

代码示例 (完整的 SqlSession 使用流程):

SqlSession sqlSession = null;
try {sqlSession = sqlSessionFactory.openSession(); // 获取 SqlSession 实例UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 获取 Mapper 接口代理对象User user = userMapper.getUserById(1); // 执行 SQL 操作// ... 其他数据库操作 ...sqlSession.commit(); // 提交事务 (如果 autoCommit = false)return user;} catch (Exception e) {if (sqlSession != null) {sqlSession.rollback(); // 回滚事务 (如果发生异常)}throw e; // 抛出异常
} finally {if (sqlSession != null) {sqlSession.close(); // 关闭 SqlSession, 释放资源}
}

总结:

SqlSession 是 MyBatis 与数据库交互的核心接口,它通过 SqlSessionFactory 工厂创建。 SqlSessionFactory 是重量级对象,负责创建和配置 SqlSession,而 SqlSession 是轻量级对象,用于执行 SQL 语句和管理事务。 理解 SqlSession 的创建方式和与 SqlSessionFactory 的关系,以及 SqlSession 的生命周期管理,对于正确使用 MyBatis 至关重要。 在 MyBatis 应用中,开发时遵循 “获取 SqlSession -> 执行数据库操作 -> 管理事务 -> 关闭 SqlSession 的标准流程,确保资源正确释放和事务的正确性。

相关文章:

MyBatis SqlSession 是如何创建的? 它与 SqlSessionFactory 有什么关系?

SqlSession 是 MyBatis 中与数据库交互的核心接口,它提供了执行 SQL 语句、管理事务、获取 Mapper 接口代理对象等关键功能。 SqlSession 实例 不是直接通过 new 关键字创建的,而是通过 SqlSessionFactory 工厂来创建的。 SqlSessionFactory 负责创建 Sq…...

【操作系统安全】任务4:Windows 系统网络安全实践里常用 DOS 命令

目录 一、引言 二、网络信息收集类命令 2.1 ipconfig 命令 2.1.1 功能概述 2.1.2 实例与代码 2.2 ping 命令 2.2.1 功能概述 2.2.2 实例与代码 2.3 tracert 命令 2.3.1 功能概述 2.3.2 实例与代码 三、网络连接与端口管理类命令 3.1 netstat 命令 3.1.1 功能概述…...

Vue 概念、历史、发展和Vue简介

一、Vue概念 官方定义: 渐进式JavaScript 框架,易学易用,性能出色,适用场景丰富的 Web 前端框架。 Vue.js 是一个流行的前端JavaScript框架,由尤雨溪(Evan You)开发并维护。 它最初于2014年发…...

【从零开始学习计算机科学】信息安全(二)物理安全

【从零开始学习计算机科学】信息安全(二)物理安全 物理安全物理安全的涵义物理安全威胁常见物理安全问题物理安全需求规划物理安全需求设备安全防盗和防毁机房门禁系统机房入侵检测和报警系统防电磁泄漏防窃听设备管理设备维护设备的处置和重复利用设备的转移电源安全电源调整…...

LeetCode hot 100—验证二叉搜索树

题目 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 示例 1&#…...

【商城实战(39)】Spring Boot 携手微服务,商城架构焕新篇

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配&#xf…...

MongoDB 可观测性最佳实践

MongoDB 介绍 MongoDB 是一个高性能、开源的 NoSQL 数据库,它采用灵活的文档数据模型,非常适合处理大规模的分布式数据。MongoDB 的文档存储方式使得数据结构可以随需求变化而变化,提供了极高的灵活性。它支持丰富的查询语言,允许…...

论文阅读笔记——LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

LoRA 论文 传统全面微调&#xff0c;对每个任务学习的参数与原始模型相同&#xff1a; m a x Φ ∑ ( x , y ) ∈ Z ∑ t 1 ∣ y ∣ l o g ( P Φ ( y t ∣ x , y < t ) ) 式(1) max_{\Phi}\sum_{(x,y)\in Z}\sum^{|y|}_{t1}log(P_{\Phi}(y_t|x,y<t)) \qquad \text{式(…...

UE5中 Character、PlayerController、PlayerState、GameMode和GameState核心类之间的联动和分工·

1. GameMode 与 GameState 关系描述 GameMode&#xff1a;定义游戏规则和逻辑&#xff0c;控制游戏的开始、进行和结束。GameState&#xff1a;存储和同步全局游戏状态&#xff0c;如得分、时间、胜利条件等。 联动方式 GameMode初始化GameState&#xff1a;GameMode在游戏…...

Redis的IO多路复用机制:高效的网络通信设计

在高并发、高性能的应用中&#xff0c;如何有效地管理和处理大量的客户端请求是一个至关重要的问题。Redis作为一个高性能的内存数据存储系统&#xff0c;面对大量并发客户端请求时&#xff0c;需要具备良好的网络通信能力。在Redis的设计中&#xff0c;IO多路复用机制是其核心…...

Ubuntu24.04 启动后突然进入tty,无法进入图形界面

问题描述 昨晚在编译 Android AOSP 14 后&#xff0c;进入了登录页面&#xff0c;但出现了无法输入密码的情况&#xff0c;且无法正常关机&#xff0c;只能强制重启。重启后&#xff0c;系统只能进入 TTY 页面&#xff0c;无法进入图形界面。 问题排查 经过初步排查&#x…...

搭建主从服务器

任务需求 客户端通过访问 www.nihao.com 后&#xff0c;能够通过 dns 域名解析&#xff0c;访问到 nginx 服务中由 nfs 共享的首页文件&#xff0c;内容为&#xff1a;Very good, you have successfully set up the system. 各个主机能够实现时间同步&#xff0c;并且都开启防…...

jenkins 配置邮件问题整理

版本&#xff1a;Jenkins 2.492.1 插件&#xff1a; A.jenkins自带的&#xff0c; B.安装功能强大的插件 配置流程&#xff1a; 1. jenkins->系统配置->Jenkins Location 此处的”系统管理员邮件地址“&#xff0c;是配置之后发件人的email。 2.配置系统自带的邮件A…...

Scala语言的计算机基础

Scala语言的计算机基础 计算机科学是一门极具挑战性和创造力的学科&#xff0c;其中编程语言是连接人类与计算机的桥梁。Scala&#xff08;特指可扩展语言&#xff09;作为一种现代编程语言&#xff0c;其设计初衷是为了简化软件开发过程&#xff0c;并结合了面向对象和函数式…...

定义模型生成数据表

1. 数据库配置 js import { Sequelize, DataTypes } from sequelize; // 创建一个 Sequelize 实例&#xff0c;连接到 SQLite 数据库。 export const sequelize new Sequelize(test, sa, "123456", { host: localhost, dialect: sqlite, storage: ./blog.db })…...

JVM中常量池和运行时常量池、字符串常量池三者之间的关系

文章目录 前言常量池&#xff08;Constant Pool&#xff09;运行时常量池&#xff08;Runtime Constant Pool&#xff09;字符串常量池&#xff08;String Literal Pool&#xff09;运行时常量池和字符串常量池位置变化方法区与永久代和元空间的关系三者之间的关系常量池与运行…...

KV 缓存简介

以下是关于 KV缓存&#xff08;Key-Value Cache&#xff09; 的简介&#xff0c;涵盖其定义、原理、作用及优化意义&#xff1a; 1. 什么是KV缓存&#xff1f; KV缓存 是Transformer架构&#xff08;如GPT、LLaMA等大模型&#xff09;在自回归生成任务&#xff08;如文本生成&…...

Mysql篇——SQL优化

本篇将带领各位了解一些常见的sql优化方法&#xff0c;学到就是赚到&#xff0c;一起跟着练习吧~ SQL优化 准备工作 准备的话我们肯定是需要一张表的&#xff0c;什么表都可以&#xff0c;这里先给出我的表结构&#xff08;表名&#xff1a;userinfo&#xff09; 通过sql查看…...

算法基础 -- ARM 体系架构设计专家的算法提升目标

算法提升目标:ARM 体系架构设计专家 1. 位运算优化 相关 ARM 知识点&#xff1a;SIMD、NEON、SVE、低功耗优化、加密计算、数据压缩 推荐题目&#xff1a; 136. 只出现一次的数字&#xff08;异或运算&#xff09;190. 颠倒二进制位&#xff08;位反转&#xff0c;ARM rbit…...

不同开发语言对字符串的操作

一、字符串的访问 Objective-C: 使用 characterAtIndex: 方法访问字符。 NSString *str "Hello, World!"; unichar character [str characterAtIndex:0]; // 访问第一个字符 H NSLog("%C", character); // 输出: H NSString 内部存储的是 UTF-16 编…...

Oracle Linux Server 7.9安装fail2ban

yum search oracle-epel-release yum install oracle-epel-release-el7 search fail2ban yum install fail2ban nano /etc/fail2ban/jail.d/00-firewalld.conf # defalut这里是设定全局设置&#xff0c;如果下面的监控没有设置就以全局设置的值设置。 [DEFAULT] # 用于指定哪…...

FPGA|Verilog-SPI驱动

最近准备蓝桥杯FPGA的竞赛&#xff0c;因为感觉官方出的IIC的驱动代码思路非常好&#xff0c;写的内容非常有逻辑并且规范。也想学习一下SPI的协议&#xff0c;所以准备自己照着写一下。直到我打开他们给出的SPI底层驱动&#xff0c;我整个人傻眼了&#xff0c;我只能说&#x…...

Windows11 新机开荒(二)电脑优化设置

目录 前言&#xff1a; 一、注册微软账号绑定权益 二、此电脑 桌面图标 三、系统分盘及默认存储位置更改 3.1 系统分盘 3.2 默认存储位置更改 四、精简任务栏 总结&#xff1a; 前言&#xff1a; 本文承接上一篇 新机开荒&#xff08;一&#xff09; 上一篇文章地址&…...

关于deepseek R1模型分布式推理效率分析

1、引言 DeepSeek R1 采用了混合专家&#xff08;Mixture of Experts&#xff0c;MoE&#xff09;架构&#xff0c;包含多个专家子网络&#xff0c;并通过一个门控机制动态地激活最相关的专家来处理特定的任务 。DeepSeek R1 总共有 6710 亿个参数&#xff0c;但在每个前向传播…...

揭秘大数据 | 9、大数据从何而来?

在科技发展史上&#xff0c;恐怕没有任何一种新生事物深入人心的速度堪比大数据。 如果把2012年作为数据量爆发性增长的第一年&#xff0c;那么短短数年&#xff0c;大数据就红遍街头巷尾——从工业界到商业界、学术界&#xff0c;所有的行业都经受了大数据的洗礼。从技术的迭…...

使用Dependency Walker和Beyond Compare快速排查dll动态库损坏或被篡改的问题

目录 1、问题描述 2、用Dependency Walker工具打开qr.dll库&#xff0c;查看库与库的依赖关系以及接口调用情况&#xff0c;定位问题 3、使用Beyond Compare工具比较一下正常的msvcr100d.dll和问题msvcr100d.dll的差异 4、最后 C软件异常排查从入门到精通系列教程&#xff…...

3.14学习总结 排序算法

插入排序&#xff1a; 1.直接插入排序 维护一个有序区&#xff0c;把元素一个个插入有序区的适当位置&#xff0c;直到所有元素都有序为止。 for (int i 0;i < n - 1;i) {//升序int end i;int temp k[end 1];while (end > 0) {if (temp < k[end]) {k[end 1] …...

Hadoop、Spark、Flink Shuffle对比

一、Hadoop的shuffle 前置知识&#xff1a; Map任务的数量由Hadoop框架自动计算&#xff0c;等于分片数量&#xff0c;等于输入文件总大小 / 分片大小&#xff0c;分片大小为HDFS默认值128M&#xff0c;可调 Reduce任务数由用户在作业提交时通过Job.setNumReduceTasks(int)设…...

本地部署 RAGFlow - 修改默认端口

本地部署 RAGFlow - 修改默认端口 1. 前提条件2. 部署 RAGFlow 1. 前提条件 确保 vm.max_map_count 不小于 262144&#xff1a; 如需确认 vm.max_map_count 的大小&#xff1a; sysctl vm.max_map_count如果 vm.max_map_count 的值小于 262144&#xff0c;可以进行重置&…...

repo init 错误 Permission denied (publickey)

一、已经生成ssh-key并设置到gerrit上 二、已经设置.gitconfig &#xff08;此步骤是公司要求&#xff0c;设置gerrit地址为一个别名之类的&#xff0c;有的公司不需要&#xff09; 然后出现下面的错误&#xff0c;最后发现忘记设置git的用户名和邮箱 1. git config --globa…...