首页 > 数据库 >MyBatis 源码分析--获取SqlSession

MyBatis 源码分析--获取SqlSession

时间:2024-06-23 20:57:07浏览次数:28  
标签:执行器 session -- executorType SqlSession 源码 executor

前言:

前文我们从源码层面梳理了 SqlSessionFactory 的创建过程,本篇我们继续分析一下 SqlSession 的获取过程。

初识 MyBatis 【MyBatis 核心概念】

MyBatis 源码分析–SqlSessionFactory

案例代码:

public class MyBatisTest {
    @Test
    public void test() throws IOException {
        //读取配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //创建 SqlSessionFactoryBuilder 对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //通过 SqlSessionBuilder 对象 解析 mybatis-config.xml 文件 构建一个SqlSessionFactory 
        SqlSessionFactory sqlSessionFactory = builder.build(is);
        //通过SqlSessionFactory构建一个SqlSession
        SqlSession session = sqlSessionFactory.openSession();
        //通过SqlSession 获取 Mapper 实例
        UserMapper userMapper = session.getMapper(UserMapper.class);
        //获取数据
		List<User> users = userMapper.findAll();
        //打印输出
        for (User user : users) {
            System.out.println(user);
        }
        //关闭资源
        session.close();
        is.close();
    }
}

本篇我们将主要对 sqlSessionFactory.openSession() 这句代码进行分析。

获取 SqlSession 源码分析

DefaultSqlSessionFactory#openSession 方法源码分析

DefaultSqlSessionFactory#openSession 方法只是调用了 DefaultSqlSessionFactory#openSessionFromDataSource 方法,并传入了默认的执行器类型、隔离级别、是否自动提交参数。

//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
public SqlSession openSession() {
	//使用默认的执行器类型(默认是SIMPLE) 默认隔离级别 非自动提交 委托给 openSessionFromDataSource 方法
	return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}

执行器类型

  • SIMPLE:简单执行器 SimpleExecutor,每执行一条 SQL,都会打开一个 Statement,执行完成后会关闭。
  • REUSE:重用执行器 ReuseExecutor,其内部会缓存一个 Map<String, Statement> ,每次编译完成的 Statement 都会进行缓存,不会关闭,可以重复使用。
  • BATCH:批量执行器,基于 JDBC 的 addBatch、executeBatch 功能,只能作用于 insert、update、delete 语句。
  • CachingExecutor:缓存执行器,使用了装饰器模式,在开启缓存的时候,会在上面三种执行器上包装一层 CachingExecutor。
package org.apache.ibatis.session;

public enum ExecutorType {
    SIMPLE,
    REUSE,
    BATCH;

    private ExecutorType() {
    }
}

DefaultSqlSessionFactory#openSessionFromDataSource 方法源码分析

DefaultSqlSessionFactory#openSessionFromDataSource 方法逻辑很简单,先获取创建 SqlSession 的必要参数,然后调用 DefaultSqlSession 的构造方法创建了 SqlSession 。

//org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
	//事务
	Transaction tx = null;
	//SqlSession
	DefaultSqlSession var8;
	try {
		//获取环境
		Environment environment = this.configuration.getEnvironment();
		//获取事务工厂
		TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
		//获取一个事务
		tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
		//根据 事务 和 执行器类型创建一个执行器
		Executor executor = this.configuration.newExecutor(tx, execType);
		//根据配置 执行器 事务提交方式创建一个默认的 SqlSession
		var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
	} catch (Exception var12) {
		this.closeTransaction(tx);
		throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
	} finally {
		ErrorContext.instance().reset();
	}

	return var8;
}

//org.apache.ibatis.session.defaults.DefaultSqlSession#DefaultSqlSession(org.apache.ibatis.session.Configuration, org.apache.ibatis.executor.Executor, boolean)
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
	this.configuration = configuration;
	this.executor = executor;
	this.dirty = false;
	this.autoCommit = autoCommit;
}

Configuration#newExecutor 方法源码分析

Configuration#newExecutor 主要是对执行器类型进行判断,然后生成执行器,并通过动态代理得到代理对象,并将执行器加入拦截器链。

//org.apache.ibatis.session.Configuration#newExecutor
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
	executorType = executorType == null ? this.defaultExecutorType : executorType;
	executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
	Object 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);
	}
	//是否开启缓存
	if (this.cacheEnabled) {
		//开启缓存 创建缓存执行器
		executor = new CachingExecutor((Executor)executor);
	}
	//责任链模式 将执行器加入拦截器链 使用JDK动态代理增强所有的拦截器 
	Executor executor = (Executor)this.interceptorChain.pluginAll(executor);
	return executor;
}

获取 SqlSession 的源码很简单,希望可以帮助到有需要的小伙伴。

欢迎提出建议及对错误的地方指出纠正。

标签:执行器,session,--,executorType,SqlSession,源码,executor
From: https://blog.csdn.net/weixin_42118323/article/details/139663294

相关文章

  • java项目中的高并发处理
    在Java面试中,当被问及项目中的高并发处理时,你可以从以下几个方面来分享经验:1.项目背景介绍简要介绍项目的业务场景和功能,以及为什么需要高并发处理。2.并发量评估描述如何评估系统需要处理的并发量,包括用户量、请求频率等。3.系统架构设计解释为应对高并发,系统架构......
  • k8s手撕架构图+详解
    1.架构图这个架构图展示了一个典型的Kubernetes集群的结构和各个组件的作用。以下是详细解释2.架构图整体介绍 ControllerPlane(控制平面)负责管理和控制整个Kubernetes集群。包含以下组件:etcd:一个分布式键值存储,存储集群的所有数据。Scheduler(调度器):负责将Pod......
  • 如何培养员工的竞争意识
    一、背景在当今快速变化的商业环境中,培养员工的竞争意识对于企业的长期成功至关重要。通过激发员工的竞争精神,企业能够提升整体绩效,增强创新能力,并在市场竞争中保持领先地位。本文将从多个方面探讨如何培养员工的竞争意识。二、明确目标设定设定清晰具体的目标:明确企业......
  • [题解]P2042 [NOI2005] 维护数列 - Splay解法
    P2042[NOI2005]维护数列一道思路不难,但实现细节很多的平衡树题,调了一天半终于做出来了w。对于初始序列,我们可以直接构建一条链(毕竟一个一个调用插入函数也可能形成一条链)。题解有递归直接构建成一棵严格平衡的二叉树的,这样也可以,常数可能会小一点。其中区间反转就是裸的文艺......
  • zhe_暑假生活_2024
    自学   英语      每天英语单词5个记录、5个就单词朗读      初中英语阅读与完形      初中英语语法与词汇      新概念英语      六下_培优   语文      每天摘抄优秀作文      古诗视频      西游记......
  • [Tkey] 与非
    解法原理1首先我们需要明白\(\operatorname{nand}\)的运算:\[\operatorname{not}(a\operatorname{nand}b)=a\operatorname{and}b\tag{1}\]这个很好理解,因为\(\operatorname{nand}\)就是这么定义的(从中文名字可以看出来)。\[(\operatorname{not}a)\operatorname{nand}(\opera......
  • SDL3 入门(3):三角形
    SDL3提供了SDL_RenderGeometry函数绘制几何图形,用法和OpenGL差不多,先定义顶点数据,然后根据顶点数据绘制几何图形。绘制三角形的代码如下:std::array<SDL_Vertex,3>origin_vertices={SDL_Vertex{{150,100},{1.0f,0.0f,0.0f,1.0f}},//topSDL_Vert......
  • 1.HTML初识
    1.认识网页(了解)问题1:网页由哪些部分组成?文字、图片、音频、视频、超链接问题2:我们看到的网页背后本质是什么?前端程序员写的代码问题3:前端的代码是通过什么软件转换成用户眼中的页面的?通过浏览器转化(解析和渲染)成用户看到的网页2.渲染引擎(浏览器内核):浏览器中专门对代码进行......
  • 使用fnm安装node,并自定义安装路径
    作者:咕魂时间:2024年6月23日本教程使用winget对fnm进行安装,主要分两部分,第一步安装fnm,第二步安装nodejs其中nodejs配置成功后只在powershell中生效1.fnm的安装假设我们自定义安装路径为:D:\fnm下载安装fnmwingetinstallSchniz.fnm--locationD:\fnm由于要从github上下......
  • 实验7
    task1//将图书信息写入文本文件data1.txt//再从文件中读取图书信息,打印输出到屏幕上,并显示行号#include<stdio.h>#defineN80#defineM100typedefstruct{ charname[N];//书名 charauthor[N];//作者}Book;//函数声明voidfunc1();voidfunc2()......