『手撕 Mybatis 源码』04 - 创建 sqlSession

news2024/11/19 20:26:22

创建 sqlSession

创建 openSession 对象

  1. 当获取 SqlSessionFactory 之后,就可以开始获取 SqlSession 对象
public class MybatisTest {

  @Test
  public void test1() throws IOException {
  ...
    // 3.问题:openSession()执行逻辑是什么?
    // 3. (1) 创建事务对象 (2)创建了执行器对象cachingExecutor (3)创建了 DefaultSqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    ...
    sqlSession.close();
  }
}
  • 其中,openSession() 支持很多种参数类型定义,主要是判断是否进行事务自动提交、数据库连接、执行器类型选择、事务隔离级别
    在这里插入图片描述
  1. 下面是走默认构造函数
public class DefaultSqlSessionFactory implements SqlSessionFactory {
	// Configuration 是 Factory.build() 的时候,封装到这里
	private final Configuration configuration;
   ...
  @Override
  public SqlSession openSession() {
    // 调用 openSessionFromDataSource 
    // 参数 1:执行器类型  
    // 参数 2:事务隔离级别
    // 参数 3:指定事务是否自动提交,默认是 false
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
  }
}
  • 其中,getDefaultExecutorType() 返回默认执行器类型,也就是 SIMPLE
public class Configuration {
  ...
  // 默认执行器类型
  protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
  ...
  public ExecutorType getDefaultExecutorType() {
    return defaultExecutorType;
  }
}
  • 执行器类型包含 SIMPLEREUSEBATCH,实现的类图如图下所示
    在这里插入图片描述
    • BaseExecutor:基础执行器,封装了子类的公共方法,包括一级缓存、延迟加载、回滚、关闭等功能
    • SimpleExecutor:简单执行器,每执行一条 sql,都会打开一个 Statement,执行完成后关闭
    • ReuseExecutor:重用执行器,相较于 SimpleExecutor 多了 Statement 的缓存功能,其内部维护一个 Map<String, Statement> ,每次编译完成的 Statement 都会进行缓存,不会关闭
    • BatchExecutor:批量执行器,基于 JDBC 的 addBatch()executeBatch() 功能,并且在当前 sql 和上一条 sql 完全一样的时候,重用 Statement,在调用doFlushStatements() 的时候,将数据刷新到数据库
    • CachingExecutor:缓存执行器,装饰器模式,在开启缓存的时候。会在上面三种执行器的外面包上 CachingExecutor
  1. openSessionFromDataSource 中,先拿到 environment 对象,根据 environment 对象里面的配置、包括数据源,创建事务工厂对象。然后根据执行器类型,利用事务管理器创建 executor 对象,最后把 configurationexecutor 封装到 DefaultSqlSession 返回
public class DefaultSqlSessionFactory implements SqlSessionFactory {

  private final Configuration configuration;
  ...
  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      // 从 configuration 对象中获取 environment 对象
      // environment 里面封装 dataSource 和 事务工厂(即配置文件上写的 type="JDBC")时候创建的
      final Environment environment = configuration.getEnvironment();
      // 获得事务工厂对象
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      // 构建事务对象
      // 看类型,才决定用哪个工厂,因为 xml 写的是 JBBC,所以用 JdbcTransactionFactory。如果是 Managed 就是交给容器来管理事务
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      // 创建执行器对象
      final Executor executor = configuration.newExecutor(tx, execType);
      // 创建 DefaultSqlSessio n对象
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
}
  1. JdbcTransactionFactorynewTransaction() 中,会返回一个 JdbcTransaction 对象,它的底层会通过一个 Connection 对象,进行 commit() 或者 rollback()
public class JdbcTransactionFactory implements TransactionFactory {
  ...
  @Override
  public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
    return new JdbcTransaction(ds, level, autoCommit);
  }
}
  1. 在使用 sqlsession 时,具体的执行是依赖执行器的,下面看看执行器的创建。根据传入的执行器类型,来对 transaction 进行封装,如果开启了 cacheEnabled 还会利用装饰者模式,对创建的 executor 再包一层,开启缓存。最后还可以使用拦截器插件也再对 executor 进行封装
public class Configuration {
  ...
  // 默认执行器类型
  protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
  // 是否启用缓存
  protected boolean cacheEnabled = true;
  ...
  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    // 装饰者模式:如果允许缓存,会通过 CachingExecutor 去代理一层
    if (cacheEnabled) { // 默认 true
      executor = new CachingExecutor(executor);
    }
    // 拦截器插件
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }
}
  1. 总结
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/554018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++学习——引用

引用 **引用的语法****引用的注意事项****数组的引用****引用的本质****尽量用const来代替define****指针的引用** 1.引用是做什么:和C语言的指针一样的功能,并且使语法更加简洁 2.引用是什么∶引用是给空间取别名 引用的语法 #define _CRT_SECURE_NO_WARNINGS #include <i…

星戈瑞Sulfo-CY7 NHS ester标记带氨基的荧光Cyanine7-NHS

Sulfo-CY7 NHS ester是一种常用的蛋白质标记试剂&#xff0c;是一种高度稳定的荧光染料&#xff0c;能够被用于各种细胞成像实验中。利用这种染料&#xff0c;科学家们可以标记细胞膜、细胞核、细胞器等&#xff0c;从而观察细胞的各种结构和功能。 产品名称&#xff1a;水溶性…

似然(likelihood)、极大似然、对数似然、最大后验等

1 似然 设总体X服从分布P(x&#xff1b;θ)&#xff08;当X是连续型随机变量时为概率密度&#xff0c;当X为离散型随机变量时为概率分布&#xff09;&#xff0c;θ为待估参数&#xff08;或者说系统参数&#xff09;&#xff0c;X1,X2,…Xn是来自于总体X的样本&#xff0c;x1…

互联网医院|互联网医院系统开发|互联网医疗平台搭建

随着互联网的快速普及&#xff0c;互联网医院成为解决医疗资源分布不平衡、基层医疗服务短缺等问题的有效途径。互联网医院系统的优势主要体现在以下几个方面&#xff1a;   1.在线挂号预约   互联网医院系统可以方便快捷地进行在线预约挂号。患者可以通过小程序或网站实现…

BI大数据分析平台,精细化分析的必备工具

在日常的工作中&#xff0c;经常会遇到要做经营决策时&#xff0c;数据分析却掉链子的情况&#xff0c;比如当老板临时提出要进一步分析某类商品的销售情况时&#xff0c;得重新开发报表。BI大数据分析平台能不能随时随地实现精细化数据分析&#xff0c;避免数据分析跟不上运营…

Python实现ACO蚁群优化算法优化Catboost分类模型(CatBoostClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蚁群优化算法(Ant Colony Optimization, ACO)是一种源于大自然生物世界的新的仿生进化算法&#xff0c…

Java | 一分钟掌握定时任务 | 7 - ElasticJob分布式定时任务

作者&#xff1a;Mars酱 声明&#xff1a;本文章由Mars酱编写&#xff0c;部分内容来源于网络&#xff0c;如有疑问请联系本人。 转载&#xff1a;欢迎转载&#xff0c;转载前先请联系我&#xff01; 前言 ElasticJob 是面向互联网生态和海量任务的分布式调度解决方案。 它通过…

pointNet、pointNet++算法学习笔记

算法结构 原理解析 已知&#xff1a; N个点&#xff0c;每个点的信息x,y,z。 MLP:全连接网络&#xff0c;输入层&#xff0c;隐藏层&#xff0c;输出层。 原理&#xff1a; &#xff08;1&#xff09;第一步 MLP 对每个点进行MLP操作&#xff0c;即&#xff1a;3–>MLP(3,C…

Spring MVC文件上传处理详解

Spring MVC文件上传处理详解 Spring MVC是Java Web开发中非常常用的框架之一&#xff0c;它提供了许多方便的功能。其中&#xff0c;文件上传是Web开发中常用的功能之一&#xff0c;本文将介绍如何使用Spring MVC处理文件上传以及相关代码实现。 文件上传的基本原理 在Web开发…

HTML-iconfont动态图标SVG效果--阿里巴巴图标矢量库

给北大打工&#xff0c;实现官网首页动态图标效果_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Ys4y1c7oh/?spm_id_from333.1007.top_right_bar_window_default_collection.content.click&vd_source924f5dad6f2dcb0a3e5dca4604287ecd&#xff08;本篇笔记操作方法…

Java 基础语法学习笔记

目录 一、Java语言概述 1.1 Java 的出现 1.2 Java的主要特性 1.3 Java语言的特点 1.4 Java语言的核心机制 1.5 Java语言的环境搭建 二、第一个Java程序 2.1 需要注意的问题 2.2 注释&#xff08;comment) 2.3 注意点&#xff1a; 2.4 Java API 的文档 2.5 第一个 Jav…

python+django智慧办公hr招聘辅助管理系统vue

随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;智慧办公hr招聘辅助管理系统当然也不能排除在外。智慧办公hr招聘辅助管理系统是以实际运用为开发背景&#xff0c;运用软件工程…

深度学习框架-Keras:特点、架构、应用和未来发展趋势

引言 深度学习是一种新兴的技术&#xff0c;已经在许多领域中得到广泛的应用&#xff0c;如计算机视觉、自然语言处理、语音识别等。在深度学习中&#xff0c;深度学习框架扮演着重要的角色。Keras是一种广泛使用的深度学习框架&#xff0c;它在许多方面都有所改进&#xff0c…

云计算基础——云计算与移动互联网、物联网

8.1 云计算与移动互联网 8.1.1 移动互联网的发展概况 移动互联网的发展概况 移动互联网是指以宽带IP为技术核心&#xff0c;可同时提供语音、数据、多媒体等业务服务的开什么是移动互联网?放式基础电信网络&#xff0c;从用户行为角度来看&#xff0c;移动互联网广义上是指用…

openldap介绍以及使用

参考文献&#xff1a;openldap介绍和使用 基本概念 官网&#xff1a;https://www.openldap.org 官方文档&#xff1a;https://www.openldap.org/doc LDAP是一个开放的&#xff0c;中立的&#xff0c;工业标准的应用协议&#xff0c;通过IP协议提供访问控制和维护分布式信息的…

目标检测 YOLOv5 开源代码项目调试与讲解实战土堆 课程笔记

P4 P5 主要讲解了 detect.py 中的参数的使用 如何利用 YOLOv5 进行预测&#xff08;一&#xff09;_哔哩哔哩_bilibili 如何利用YOLOv5进行预测&#xff08;二&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;weight&#xff1a;代码如下 parser.add_argument(--w…

VTKmimics Calculate Parts

前言&#xff1a;本博文主要研究mimics中Calculate Parts所采用的方法以及VTK中三维重建的方法&#xff0c;希望对各位小伙伴有所帮助&#xff0c;谢谢&#xff01; mimics-Calculate parts - Interpolation Gray Interpolation 灰度值插值是一种真正的3D插值&#xff0c;它考…

【C++学习第十一讲】C++数据类型

文章目录 一、编程语言中的数据类型1.1 整型&#xff08;Integer&#xff09;1.2 浮点型&#xff08;Floating-Point&#xff09;1.3 字符型&#xff08;Character&#xff09;1.4 布尔型&#xff08;Boolean&#xff09;1.5 数组&#xff08;Array&#xff09;1.6 字符串&…

TitanIDE:环境安装部署教程

随着市场需求的迅速增长和技术的不断发展&#xff0c;云原生不仅仅是一种技术&#xff0c;更是一种思想。它通过容器化、微服务化、自动化等技术手段&#xff0c;推动了应用程序设计和交付的转变&#xff0c;使应用程序的开发、测试、部署和管理变得更加高效和灵活。 随着市场需…

【多线程】| 线程冲突解决方案

目录 &#x1f981; 线程同步1.什么是线程冲突&#xff1f;2.什么是线程同步&#xff1f;3.解决线程同步的方案3.1语法结构3.2synchronized使用 &#x1f981; synchronized详细用法1. 使用this作为线程锁对象1.1 语法结构&#xff1a;1.2 使用说明 2. 使用字符串作为线程对象锁…