2. Spring Boot 自动配置 Mybatis 流程
1. Spring Boot 自动配置 Mybatis
自动配置过程中做了3个主要bean的创建及很重要的一些事情。
- sqlSessionFactory、sqlSessionTemplate、MapperScannerConfigurer 等配置bean的创建。
- sqlSessionFactory:解析 xml配置文件,并将MappedStatement放入到HashMap中。
- sqlSessionTemplate:代理了 DefaultSqlSession,增强了Session的创建获取、关闭、事务等能力。
- MapperScannerConfigurer:扫描@Mapper注解,并生成这些类的BeanDefinition放入到注册表中。
自动配置
约定大于配置,缺省的配置看这个注解 @EnableConfigurationProperties({MybatisProperties.class})。这个注解中引入了MybatisProperties类,包含了一些默认的配置。
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {}
MybatisAutoConfiguration的主要属性有:
- MybatisProperties:yaml文件中的属性配置
- Interceptor[] :拦截器数组
- TypeHandler[] :类型解析器等
构造方法:
- 从 yaml 文件中获取 mybatis 前缀的属性封装成对象
MybatisProperties,赋值给 properties 。 - 获取拦截器
- 获取typeHandlers
- 其他。。。
创建 sqlSessionFactory
前提:
- 依赖DataSource 数据源 @ConditionalOnSingleCandidate(DataSource.class)。要求 BeanFactory 中存在指定类并且可以确定单个候选项才会匹配成功
- 在数据源完成自动配置之后配置 sqlSessionFactory = new SqlSessionFactoryBean().getObject();
正文:
-
创建一个工厂bean:
MybatisSqlSessionFactoryBean -
工厂 bean 设置数据源dataSource。依赖注入,此时容器中已经有了dataSource,直接拿来用。
-
初始化配置属性
- 如果有配置 mybatis-config.xml 则设置configLocation 属性。
- 应用yaml 文件中嵌套配置 configuration到 factoryBean。
- TypeHandler
- 拦截器
-
通过工厂Bean的getObject方法获取sqlSessionFactory。
-
对关键配置做断言处理:
dataSource、sqlSessionFactoryBuilder、configuration、configLocation -
buildSqlSessionFactory:开始构建sqlSessionFactory。-
如果配置项 mapperLocation不为空,循环解析每一个 mapper.xml文件
-
XMLMapperBuilder.parse() 解析xml 文件
-
如果没有解析过该 xml 文件,则进行解析,如果解析过,直接跳过。
-
configurationElement解析mapper 节点<mapper namespace="com.pansnow.changcheng.mapper.UserMapper"><select id="queryUserList" resultType="com.pansnow.changcheng.pojo.User">select *from user</select><insert id="addUser" parameterType="com.pansnow.changcheng.pojo.User">insert into user(id, name, pwd)values (#{id}, #{name}, #{pwd});</insert><update id="updateUser" parameterType="com.pansnow.changcheng.pojo.User">update userset name=#{name},pwd=#{pwd}where id = #{id};</update><delete id="deleteUser" parameterType="int">deletefrom userwhere id = #{id};</delete> </mapper> -
namespace判空。namespace 为 mapper 接口类的 String 字符串
-
解析 parameterMap 和 resultMap节点
-
解析 sql节点
-
解析 select|insert|update|delete
-
-
将该文件添加到已解析集合中。
protected final Set<String> loadedResources; if (!this.configuration.isResourceLoaded(this.resource)) {...this.configuration.addLoadedResource(this.resource);... } -
将 mapper 类添加到 mapper注册表中。
private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap();this.knownMappers.put(type, new MapperProxyFactory(type));-
knownMapper是一个mapper接口类和他的代理工厂的一个映射。
-
解析 mapper 类上的注解@Select、@SelectProvider、@ResultMap 等注解,用于解析 mapper 类中方法上的 SQL 语句。
-
解析方法上的xml文件中的 SQL语句 parseStatement。
- 具体的解析过程就不谈了,太复杂,先不看了。
-
MybatisSqlSessionFactoryBean中有一个属性mappedStatements。这是一个 HashMap - 将解析过后的
MappedStatement添加到 map 中
-
-
-
创建sqlSessionTemplate
-
使用 jdk 动态代理,创建SqlSessionProxy,增强逻辑为
SqlSessionInterceptor。代理了SqlSession的创建和获取、事务、关闭。即在调用SqlSession接口中的每一个方法时,都会调用SqlSessionInteceptor的invoke逻辑。 -
SqlSessionInterceptor的逻辑为:-
创建SqlSession。使用 selSessionFactory
代理对象是如何获取defaultSqlSession ,在代理方法中通过SqlSessionUtils 的方法获取SqlSession
- 它会首先获取SqlSessionHolder,SqlSessionHolder用于在TransactionSynchronizationManager中保持当前的SqlSession。
- 如果holder不为空,并且holder被事务锁定,则可以通过holder.getSqlSession()方法,从当前事务中获取sqlSession,即 Fetched SqlSession from current transaction。
- 如果不存在holder或没有被事务锁定,则会创建新的sqlSession,即 Creating a new SqlSession,通过sessionFactory.openSession()方法。
- 如果当前线程的事务是活跃的,将会为SqlSession注册事务同步,即 Registering transaction synchronization for SqlSession。
SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);-
如果 session 为 null,
- 利用事务工厂创建一个事务,
- 新建一个 Executor:这个是干嘛的,不太清楚哇。
- 新建一个 DefaultSqlSession。
- 创建sqlSessionHolder 将 sqlSession 包起来。
- 将sqlSessionHolder存放到
TransactionSynchronizationManager的synchronizations中。synchronizations是一个 set 集合。
-
调用业务方法
-
如果有事务,提交事务
-
关闭 session。关闭前会释放 holder。
holder.released();SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
-
创建MapperScannerRegistrarNotFoundConfiguration
主要在于根据配置创建MapperScannerConfigurer,
@Import({AutoConfiguredMapperScannerRegistrar.class}) 这个AutoConfiguredMapperScannerRegistrar类非常关键,因为他在扫描@Mapper 注解
-
BeanDefinitionBuilder:创建MapperScannerConfigurer的 BeanDefinitionBuilder - 设置扫描注解类:Mapper.class
- 设置扫描包路径
- 设置sqlSessionFactoryBeaName
- 设置 sqlSessionTemplateBeanName
- 注册
MapperScannerConfigurer到注册表中
MapperScannerConfigurer
实现了 BeanDefinitionRegistryPostProcessor ,工作在bean 定义的注册阶段。
扫描@Mapper 注解,为什么需要单独处理呢?因为 Mapper 注解是 mybatis 自定义注解,和 Component 注解没有关系。这个类会将@Mapper 注解下的类也实例化后放入到 Spring 容器中。
负责扫描Mapper接口的扫描器为ClassPathMapperScanner,他是ClassPathBeanDefinitionScanner的子类。ClassPathMapperScanner扫描到注解类后,会为其生成BeanDefinition。这里生成的是一个MapperFactoryBean的bean定义。
- 生成bean定义的时候,将bean定义的name设置为userMapper。但是其类型设置为了MapperFactoryBean。
-
mapperInterface 设置为了 com.pansnow.changcheng.mapper.UserMapper -
factoryBeanObjectType设置为了 com.pansnow.changcheng.mapper.UserMapper - 加了个
sqlSessionTemplate的属性,引用指向容器中的bean:sqlSessionTemplate
然后在后期创建bean的时候,MapperFactoryBean会执行getObject方法
-
knownMapper是一个mapper接口类和他的代理工厂的一个映射。
-
MapperProxyFactory代理工厂创建mapperProxy 代理mapper接口。
this.getSqlSession().getMapper(this.mapperInterface);||\||/ this.mapperRegistry.getMapper(type, sqlSession);||\||/ MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type); return mapperProxyFactory.newInstance(sqlSession); -
mapperProxy在执行方法的时候,会从DefaultSqlSession的Configuration中获取方法对应的MappedStatement。接下来就很明白了。
相关文章:
2. Spring Boot 自动配置 Mybatis 流程
1. Spring Boot 自动配置 Mybatis 自动配置过程中做了3个主要bean的创建及很重要的一些事情。 sqlSessionFactory、sqlSessionTemplate、MapperScannerConfigurer 等配置bean的创建。sqlSessionFactory:解析 xml配置文件,并将MappedStatement放入到Has…...
Nginx配置反向代理实例一
Mac 安装Nginx教程 提醒一下:下面实例讲解是在Mac系统演示的; 反向代理实例一实现的效果 在浏览器地址栏输入www.testproxy.com, 跳转到系统Tomcat主页面。 第一步:在系统的 hosts 文件进行ip和域名对应关系的配置。 Mac 系统修改Hosts文…...
训练自己的GPT2
训练自己的GPT2 1.预训练与微调2.准备工作2.在自己的数据上进行微调 1.预训练与微调 所谓的预训练,就是在海量的通用数据上训练大模型。比如,我把全世界所有的网页上的文本内容都整理出来,把全人类所有的书籍、论文都整理出来,然…...
etcd储存安装
目录 etcd介绍: etcd工作原理 选举 复制日志 安全性 etcd工作场景 服务发现 etcd基本术语 etcd安装(centos) 设置:etcd后台运行 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册…...
如何彻底卸载Microsoft Edge浏览器
一、引语 随着微软推出全新的Edge浏览器,许多用户可能想要尝试或完全切换到其他浏览器。在这篇文章中,我们将向您介绍如何彻底卸载Microsoft Edge浏览器,以确保您的系统干净整洁。 二、通过系统设置卸载 1、首先,右键单击桌面上…...
Transformers 2023年度回顾 :从BERT到GPT4
人工智能已成为近年来最受关注的话题之一,由于神经网络的发展,曾经被认为纯粹是科幻小说中的服务现在正在成为现实。从对话代理到媒体内容生成,人工智能正在改变我们与技术互动的方式。特别是机器学习 (ML) 模型在自然语言处理 (NLP) 领域取得…...
判断两个对象某些字段的值是否相同
1、借助mybatis plus的方法 import com.baomidou.mybatisplus.core.toolkit.LambdaUtils; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda; import lombok.SneakyThrows; import o…...
TYPE-C接口取电芯片介绍和应用场景
随着科技的发展,USB PDTYPE-C已经成为越来越多设备的充电接口。而在这一领域中,LDR6328Q PD取电芯片作为设备端协议IC芯片,扮演着至关重要的角色。本文将详细介绍LDR6328Q PD取电芯片的工作原理、应用场景以及选型要点。 一、工作原理 LDR63…...
基于TI TPSXX系列 Buck电路应用计算-外围器件详细计算过程
TPS54202 Buck电路应用计算 1、电气特性2、内部框图3、典型应用电路4、设计需求5、计算EN引脚电阻6、FB引脚电阻估算7、查看反馈电压电压基准8、输入电容计算10、FB引脚反馈电阻计算11、功率电感计算12、输出电容计算13、前馈电容计算15、Layout布局TPS54202-中文版 1、电气特…...
NOIP2012提高组day1-T3:开车旅行
题目链接 [NOIP2012 提高组] 开车旅行 题目描述 小 A \text{A} A 和小 B \text{B} B 决定利用假期外出旅行,他们将想去的城市从 1 1 1 到 n n n 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同…...
Golang Web框架性能对比
Golang Web框架性能对比 github star排名依次: Gin Beego Iris Echo Revel Buffalo 性能上gin、iris、echo网上是给的数据都是五星,beego三星,revel两星 beego是国产,有中文文档,文档齐全 根据star数,性能,易用程度…...
【OCR】 - Tesseract OCR在mac系统中安装
Tesseract OCR 在Mac环境下安装Tesseract OCR(Optical Character Recognition)通常可以通过Homebrew包管理器进行。以下是安装步骤: 安装Homebrew 如果你还没有安装Homebrew,请访问 https://brew.sh/ 并按照页面上的说明安装。…...
了解不同方式导入导出的速度之快
目录 一、用工具导出导入 Navicat(速度慢) 1.1、导入: 共耗时: 1.2、导出表 共耗时: 二、用命令语句导出导入 2.1、mysqldump速度快 导出表数据和表结构 共耗时: 只导出表结构 导入 共耗时&…...
2024年第九届计算机与通信系统国际会议(ICCCS2024) ,邀您相约西安!
会议官网: ICCCS2024 | Xian China 时间: 2024年4月19-22日 地点: 中国西安 会议简介: 近年来,信息通信在不断发展,为计算机网络的进步与发展提供了先进可靠的技术支持。随着计算机网络与通信技术的深入发展,计算机通信技术、数…...
获取直播间的最新评论 - python 取两个list的差集
python 取两个list的差集 作用:比如我要获取评论区列表,先获取了一遍,这个时候有人评论了几条,我再获取一遍后,找出多的那几条 使用set数据类型来取两个列表的差集。差集表示仅包含在第一个列表中而不在第二个列表中…...
2023年度总结:但行前路,不负韶华
🦁作者简介:一名喜欢分享和记录学习的在校大学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS &#x…...
智数融合|低代码入局,推动工业数字化转型走"深"向"实"
当下,“数字化、智能化”已经不再是新鲜词汇。事实上,早在几年前,就有企业开始大力推动数字化转型,并持续进行了一段时间。一些业内人士甚至认为,“如今的企业数字化已经走过了成熟期,进入了深水区。” 但事…...
初学者的基本 Python 面试问题和答案
文章目录 专栏导读1、什么是Python?列出 Python 在技术领域的一些流行应用。2、在目前场景下使用Python语言作为工具有什么好处?3、Python是编译型语言还是解释型语言?4、Python 中的“#”符号有什么作用?5、可变数据类型和不可变…...
支持向量机(Support Vector Machines,SVM)
什么是机器学习 支持向量机(Support Vector Machines,SVM)是一种强大的机器学习算法,可用于解决分类和回归问题。SVM的目标是找到一个最优的超平面,以在特征空间中有效地划分不同类别的样本。 基本原理 超平面 在二…...
golang一个轻量级基于内存的kv存储或缓存
golang一个轻量级基于内存的kv存储或缓存 go-cache是一个轻量级的基于内存的key:value 储存组件,类似于memcached,适用于在单机上运行的应用程序。 它的主要优点是,本质上是一个具有过期时间的线程安全map[string]interface{}。interface的结…...
DownKyi终极指南:快速掌握B站视频批量下载与8K超高清获取技巧
DownKyi终极指南:快速掌握B站视频批量下载与8K超高清获取技巧 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等…...
Ubuntu服务器性能检测工具NetData安装
1. NetData安装 打开Ubuntu终端并输入以下指令: $ bash <(curl -Ss https://my-netdata.io/kickstart-static64.sh)中途会提示安装文件将为占用磁盘空间,是否继续(Y/N),输入Y即可,安装完成后的截图如下…...
清华PPT模板:5分钟打造专业学术演示的终极方案
清华PPT模板:5分钟打造专业学术演示的终极方案 【免费下载链接】THU-PPT-Theme 清华主题PPT模板 项目地址: https://gitcode.com/gh_mirrors/th/THU-PPT-Theme 还在为每一次学术汇报、论文答辩或教学课件而烦恼吗?THU-PPT-Theme清华PPT模板库为你…...
近屿AI学:白天做运维,晚上学AI,两天入职
何屿(化名)白天还在做传统运维,晚上已经开始补AI课程。听起来有点折腾,但他比谁都清楚,稳定并不等于安全。AI兴起后,岗位要求正在变,旧经验能撑多久,他心里没底。与其等到被动调整&a…...
AI模型API网关:统一管理多厂商大模型调用,实现高效治理与成本控制
1. 项目概述与核心价值最近在折腾AI应用开发,发现一个挺普遍的问题:当你的应用需要同时调用多个不同厂商的大模型API时,管理起来简直是一场噩梦。每个厂商的接口地址、认证方式、请求格式、计费逻辑都不一样,更别提还有速率限制、…...
作为一个网聊经常冷场的人,我试了试几款聊天回复神器
平时在线下跟人沟通还好,但一到微信或者Soul这种线上聊天环境,我就特别容易卡壳。尤其是遇到对方发来一些带有情绪的话,我经常不知道怎么接,打了一堆字又默默删掉,最后回个“哈哈”或者“早点休息”,硬生生…...
异构推测解码技术:加速大语言模型推理的突破方案
1. 项目概述:异构推测解码技术解析在自然语言处理领域,大语言模型(LLM)的推理速度一直是制约其实际应用的关键瓶颈。传统自回归生成方式需要逐个token顺序输出,导致高延迟问题。推测解码(Speculative Decod…...
企业真正缺的不是模型,而是“AI 协作系统”
过去两年,大模型的发展速度远远超出了很多人的预期。 模型越来越强,推理成本越来越低,开源生态也越来越成熟。 很多企业因此开始接入 AI,希望通过大模型提升效率。 但真正进入业务阶段后,一个问题开始越来越明显&am…...
收藏!小白程序员必看:大模型时代高薪就业新机遇与学习路径
收藏!小白程序员必看:大模型时代高薪就业新机遇与学习路径 2026年中国就业市场面临高校毕业生激增与岗位结构性短缺的矛盾,传统岗位被AI替代,而AI工程师、智能驾驶等高薪岗位却人才紧缺。核心原因是技能断层,企业需要复…...
openpilot终极指南:从开源机器人操作系统到300+车型自动驾驶辅助实现
openpilot终极指南:从开源机器人操作系统到300车型自动驾驶辅助实现 【免费下载链接】openpilot openpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars. 项目地址: https://gitcode.com/G…...
