Mybatis源码总结

mybatis

Mybatis是一个orm框架,帮助我们更好的在java中编写和管理SQL语句
主要的运行过程:

  1. 主配置文件,配置mapper文件的位置,以及数据源,缓存,插件等配置信息,项目运行起来后会解析该文件,相关信息存储在Configuration对象中
  2. mapper文件,写sql,与mapper接口对应起来,实现sql和java代码分离,通过解析,会保存在Configuration对象中,key:全路径类名+方法名 ,value:MappedStatement对象,里面包含该方法sql的各种信息,二级缓存在该对象中
  3. sqlSession是主要的类,用来执行sql的增删改查,要生成它需要一个SqlSessionFactory工厂类,生产出来的sqlSession实现类DefaultSqlSession,其中一级缓存就是在这个类中
  4. sqlSession执行增删改查操作;也可以通过获取Mapper接口,通过接口来进行sql方法调用,获取到的Mapper接口是通过jdk的动态代理生成代理对象完成的,主要的动态代理逻辑在MapperProxy类中,然后通过调用sqlSession的增删改查方法进行sql执行。
  5. 下面介绍sqlSession的实现类DefaultSqlSession的select方法过程涉及到的重要类以及过程
    1. Executor:SqlSessionFactory的openSession在创建Executor的时候会把插件对应的拦截了该类中的方法进行动态代理,完成增强,该执行器的作用是生成sql语句(**MappedStatement 中的语句生成工具 **通过xml中写的sql是否有需要填充属性的分为动态sql和原始sql),以及一二级缓存的获取和更新,在这里通过Transaction获取数据库连接
    2. StatementHandler:也可以通过插件 进行拦截的方法,会创建ResultSetHandlerParameterHandler然后通过connection创建生成jdbc的PreparedStatement,然后调用parameterHandler填充参数
    3. ParameterHandler:使用paredStatement的setxxxx方法填充参数,在填充的时候要知道要填充的数据类型对应sql的数据类型,好调用对应的paredStatement的setxxx方法,这个时候需要TypeHandler的各种类型的实现,来调用paredStatement.setxxx方法
    4. 最后执行paredStatement.execute(sql)
    5. ResultSetHandler:处理执行后返回的jdbc的ResultSet,这里也需要TypeHandler处理数据库类型和java类型对应起来,调用对应的实现类的方法,设置给对应的java对象的属性

mybatis-spring

mapper对象注入IOC容器

  1. 通过**@MapperScan**注解导入MapperScannerRegistrar(实现ImportBeanDefinitionRegistrar)->MapperScannerConfigurer(实现的BeanDefinitionRegistryPostProcessor)->**ClassPathMapperScanner#doScan**要扫描所有的mapper接口,beandefinition改成MapperFactoryBean的class,设置MapperFactoryBean的各种属性,比如:当前mapper接口的的全路径类名,SqlSessionTemplate对象
  2. MapperFactoryBean:这是实现了FactoryBean接口,getObject中通过sqlSession#getMapper获取到对应Mapper的动态代理后的对象, 每个Mapper接口都有一个MapperFactoryBean

sqlSessionTemplate:

  1. 里面通过动态代理SqlSessionInterceptor,修改获取SqlSession的逻辑,主要是为了同一个事务线程中可以共用sqlSession,存储在threadLocal中。同时注入几个事务状态感知钩子类(通过TransactionSynchronizationManager.registerSynchronization())
  2. 真正干活的sqlSession还是通过SqlSessionFactory生成DeFaultSqlSession

mybatis-spring和spring事务

在mybatis中,负责事务处理的接口是Transaction(里面设置数据源);主要功能用来获取连接,事务提交和回滚

mybatis和spring整合后不会连接获取和进行提交事务,统一交给spring jdbc中的事务处理。
通过实现了mybatis中Transaction接口的SpringManagedTransaction类,该类中的获取连接又调用spring-jdbc中的工具获取,同时通过isConnectionTransactional属性控制不能再该类中进行提交和回滚,统一把这些回滚和提交工作交给spring事务框架。

spring事务处理大致流程:

  1. 通过TransactionInterceptor拦截器拦截目标方法
  2. 通过DataSourceTransactionManager获取事务,主要获取数据库连接资源并绑定到当前线程中的(TransactionSynchronizationManager),以及参数设置,read only参数会执行sql.
  3. 存储当前事务信息到TransactionInfo.oldTransactionInfo中,事务传播的时候需要
  4. 执行mapper的方法。MapperProxy代理(mybatis-plus中是MybatisMapperProxy); sqlSession是SqlSessionTemplate->SqlSessionInterceptor(动态代理,会通过sqlsession工厂获取sqlSession,并且作为资源绑定到当前线程中,所以同一个事务中可以使用一级缓存
  5. 提交或者回滚事务
    1. 提交事务
      1. triggerBeforeCommit :触发TransactionSynchronization#beforeCommit, 重要实现:mybatis-spring整合中有个SqlSessionUtils.SqlSessionSynchronization.beforeCommit,会执行sqlSession的commit,并不会在这里提交事务(因为事务管理使用了SpringManagedTransaction),只是刷掉sqlSession的缓存等
      2. triggerBeforeCompletion:触发触发TransactionSynchronization#beforeCompletion ,重要实现:mybatis-spring整合中有个SqlSessionUtils.SqlSessionSynchronization.beforeCompletion,会执行sqlSession.close方法,关闭sqlSession
      3. 传播级别嵌套事务的时候,子事务执行的时候,如果有回滚点,释放掉回滚点
      4. 事务执行提交操作,connection.commit()
      5. TransactionSynchronization.afterCommit
      6. 释放资源,数据库连接资源

TransactionSynchronizationManager:管理线程中的事务状态,以及事务资源在线程中的绑定,比如:数据库连接
ResourceHolderSupport:事务中的资源通过该基类,他实现了通过计数方式看当前是否释放资源 ,比如:ConnectionHolder,SqlSessionHolder
TransactionSynchronization: 可以实现钩子函数,在事务执行各个状态可以感知到

事务挂起:就是保留现有的连接,参数信息,等资源,用对象保存起来。然后清空当前线程的资源,重新获取连接

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

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

相关文章

数据库Mysql学习day01课堂笔记

一、数据库概述及数据准备 1.什么是数据库?什么是数据库管理系统?什么是SQL?他们之间的关系是什么? 数据库: 英文单词DateBase,简称DB。按照一定格式存储数据的一些文件的组合。顾名思义,存储数据的仓库,实际上就是一堆文件,这些文件中存储了具有特定格式的数据。 数…

Jtti:Linux内核怎么通过inline hook实现隐藏进程

在Linux内核中通过inline hook来隐藏进程是一种比较敏感和高级的操作,需要深入理解Linux内核的运作原理和对内核的深度了解。请注意,修改内核行为可能会导致系统不稳定,并且这种操作可能违反系统的安全策略,因此在进行此类操作之前…

民族服装数据研究:市场销售规模将突破百亿元

民族服饰文化内涵丰富,包括制作原料、纺织工艺、印染工艺、刺绣工艺、图案纹样、色彩表现、饰品工艺、文化价值等因素。我国民族服装在经历了过去30年全面工业化、经济高速增长、服装定制人口激增、大量生产、大量服装定制制消费到全国中产阶级化,人们对…

前端开发 5: Vue.js 框架

在前端开发中,Vue.js 是一个流行且灵活的 JavaScript 框架,用于构建用户界面。它采用了组件化的开发方式,使得前端开发更加模块化和可维护。在本篇博客中,我将为你介绍 Vue.js 的基础知识和常用技巧,帮助你更好地掌握前…

文档翻译网站有哪些?这些工具高效翻译

文档翻译网站有哪些?随着全球化的加速,跨语言沟通变得越来越重要。然而,语言差异常常成为我们与世界各地人们交流的障碍。为了解决这个问题,文档翻译软件应运而生。今天,我们就来介绍一些受欢迎的文档翻译软件&#xf…

【Docker】安装nacos以及实现负载均衡

🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于Docker的相关操作吧 目录 🥳🥳Welcome 的Huihuis Code World ! !🥳🥳 前言 一.nacos单个部署 1.镜像拉取 …

4.C++类和对象

深拷贝和浅拷贝的简单理解:

SpringBoot多环境配置及日志记录器

Spring Boot多环境配置 Spring Boot的针对不同的环境创建不同的配置文件, 语法结构:application-{profile}.properties profile:代表的就是一套环境 需求 application-dev.yml 开发环境 端口8090 application-test.yml 测试环境 端口8091 applica…

广东省第三届职业技能大赛“网络安全项目”B模块--数字取证解析

广东省第三届职业技能大赛“网络安全项目”B模块任务书 PS: 关注鱼影安全第一部分 网络安全事件响应第二部分 数字取证调查任务 3: 网络数据包分析取证解析:第三部分 应用程序安全:需要环境可以私信博主~PS: 关注鱼影安全 模块 B 竞赛项目试题 本文件为:广东省第三届职业技…

如何用mysql或者zk分配​​机器id

大家好,我是三叔,新的一年很高兴又和大家见面了,祝各位读者龙年大吉。 在 MySQL 中,可以使用自增主键来为每个记录分配唯一的机器 ID。创建一个包含自增主键的表,每当插入新记录时,MySQL 会自动为其分配一…

提纲框架写作方法

论文提纲 论文提纲的意义 有利于检查构思有利于调整修改和写作 拟定提纲的目的 拟标题写总论点做总安排:几个方面,什么顺序做下位论点:每个项目的下位论点,直到段一级,写段的论点句考虑各段安排,把材料…

2024 前端高频面试题之 HTML/CSS 篇

【前言】随着市场的逐渐恶劣,通过总结面试题的方式来帮助更多的coder,也是记录自己的学习过程,温故而知新。欢迎各位同胞大大点评补充~ 前端面试题之 HTML/CSS 篇 1、HTML 语义化?2、块级元素&内联样式3、盒子模型的理解&…

机器学习:holdout法(Python)

import pandas as pd import numpy as np from sklearn.preprocessing import LabelEncoder, StandardScaler # 类别标签编码,标准化处理 from sklearn.decomposition import PCA # 主成分分析 import matplotlib.pyplot as plt from sklearn.model_selection impor…

springboot 原理分析之自动配置

一、Condition Condition 是在 Spring 4.0 增加的条件判断功能,通过这个可以功能可以实现选择性的创建 Bean 操作。比如说,只有满足某一个条件才能创建这个 Bean,否则就不创建。 SpringBoot 是如何知道要创建哪个 Bean 的?比如 Sp…

openGauss:准备知识1【IP地址/SSH协议/PuTTY安装和使用】

最近研究在openEuler 22.03 LTS上使用openGauss数据库。如果想要远端访问服务器,那么就先要了解IP地址、SSH协议等内容。 IP代表“Internet Protocol”,是一种网络协议,它定义了计算机在网络上的地址和数据传输方式。简言之,可以…

JAVA正则表达式第二个作用:爬取

目录 本地数据爬取: 本地爬取练习: 网络爬取: ----- 以下为均本地数据爬取: 带条件爬取 贪婪爬取和非贪婪爬取: 例题 1:使获取 1 为不贪婪 *例题 2:使获取 0、1 都为不贪婪 之前介绍了正…

Linux 系统中忘记了用户密码,可以通过以下步骤来重置密码

如果你在 Linux 系统中忘记了用户密码,可以通过以下步骤来重置密码: 通过 root 用户重置密码: 进入恢复模式: 重新启动计算机。在 GRUB 启动画面选择引导项时,选择 "恢复模式" 或 "恢复模式 with netw…

【数据结构】- 单链表

先创建好SList.c、Test.c两个源文件和SList.h一个头文件。 SList.c和Test.c一样 SList.h 文件 在SList.h加上 1.单链表打印 SList.h SList.c 思路: 逻辑图(之后经常用到): 物理图: 为了方便运行Test.c中的运行还要在…

洛谷-[NOIP1996 提高组]-挖地雷

[NOIP1996 提高组] 挖地雷 题目描述 在一个地图上有 N ( N ≤ 20 ) N\ (N \le 20) N (N≤20) 个地窖,每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,…

链表中倒数最后k个结点

链表中倒数最后k个结点 链表中倒数最后k个结点_牛客题霸_牛客网输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。。题目来自【牛客题霸】https://www.nowcoder.com/practice/886370fe658f41b498d40fb34ae76ff9 描述 输…