【手撕MyBatis源码】Configuration配置体系

news2024/11/20 14:34:57

文章目录

  • Configuration概述
  • Configuration的核心作用与配置来源
  • 配置元素
  • 元素承载
  • 配置文件解析
    • XML文件解析流程
    • 注解配置解析

Configuration概述

Configuration 是整个MyBatis的配置体系集中管理中心,前文所说的Executor、StatementHandler、Cache、MappedStatement…等绝大部分组件都是由它直接或间接的创建和管理。此外影响这些组件行为的属性配置也是由它进行保存和维护。如cacheEnabled、lazyLoadingEnabled … 等。所以说它MyBatis的大管家很形象。

Configuration是MyBatis中极其重要的一个类,它代表MyBatis的全局配置信息。

Configuration中包含了很多关键信息,主要包括:

  1. environments:存储了多个环境信息,每个环境都有transactionFactory和dataSource;
  2. mappers:存储了所有mapper文件的位置信息;
  3. mappedStatements:存储了所有mappedStatement的信息,每个mappedStatement代表一条SQL语句;
  4. resultMaps:存储了所有resultMap的信息,resultMap代表结果集映射;
  5. parameterMap:旧版本使用,已废弃;
  6. keyGenerators:存储了所有keyGenerator的信息,keyGenerator用于生成主键;
  7. typeHandlers:存储了所有typeHandler的信息,typeHandler用于javaType和jdbcType之间的转换;
  8. objectFactory:对象工厂,用于实例化目标对象;
  9. objectWrapperFactory:对象包装工厂,用于给目标对象创建代理对象;
  10. interceptors:存储了所有Interceptor的信息,Interceptor用于拦截器执行SQL;
  11. databaseIdProvider:根据databaseId获取对应的mappedStatement;
  12. logImpl:日志工厂;
  13. cache:缓存命名空间;
  14. 等等。

Configuration保存的所有这些信息构成了MyBatis一次会话(SqlSession)的全部配置环境。每开启一个新的 SqlSession 都会根据 Configuration 来构建出 SqlSession 需要的所有信息

所以简而言之,Configuration存储了MyBatis的全局配置信息,代表了一个MyBatis配置环境,它包含了SQL映射语句、结果集映射、缓存机制等等信息,这些信息构成了一个MyBatis一次会话需要的所有配置内容。

  • 当我们调用SqlSessionFactoryBuilder.build(reader)构建SqlSessionFactory时,底层会根据配置文件来构建一个Configuration对象

  • 当我们调用openSession()开启一个会话时,SqlSession由一个Configuration以及执行器(Executor)组成,这个Configuration就是前面构建的全局配置信息。

所以可以看出,Configuration对MyBatis来说意义重大,它包含了MyBatis会话所需要的全部配置资源和环境信息。没有Configuration,则根本无法构建SqlSession,也就无法工作了。

Configuration的核心作用与配置来源

Configuration 配置来源有三项:

  • Mybatis-config.xml 启动文件,全局配置、全局组件都是来源于此。
  • Mapper.xml SQL映射(MappedStatement) \结果集映射(ResultMapper)都来源于此。
  • @Annotation SQL映射与结果集映射的另一种表达形式。

在这里插入图片描述

然后我们再说说Configuration的核心作用:

  • 存储全局配置信息,其来源于settings(设置)
  • 初始化并维护全局基础组件
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • plugins(插件)
    • environments(环境配置)
    • cache(二级缓存空间)
  • 初始化并维护MappedStatement
  • 组件构造器,并基于插件进行增强
    • newExecutor(执行器)
    • newStatementHandler(JDBC处理器)
    • newResultSetHandler(结果集处理器)
    • newParameterHandler(参数处理器)

这里我们为什么要使用Configuration进行Executor的创建?原因如下:

1、根据配置的类型创建

2、是否开启缓存

3、使用interceptorChain引入插件

这样做到了统一的包装,标准化创建组件。
在这里插入图片描述

其他几个组件的创建也是一样:

在这里插入图片描述

我们来说说几个组件:

mapperRegistry

用来注册mapper接口,并生成其动态代理对象。
caches

缓存,应用级跨会话的,所有的缓存装载好了之后都会放在Configuration里面。然后mappedStatement会与我们的缓存做一个关联操作,并且他们俩之间是1:1的关系。

TypeAliasRegistry

TypeAliasRegistry是MyBatis中用于保存类型别名的注册中心。
在MyBatis中,我们可以使用<typeAlias>标签来为Java类型配置别名,如:

<typeAlias type="com.someapp.model.User" alias="User"/>

这会使User成为com.someapp.model.User类型的别名,在后续映射文件中可以直接使用User来代表那个类型。

那么,MyBatis是如何实现这个类型别名功能的呢?

这就要依赖TypeAliasRegistry了

  • TypeAliasRegistry中保存了所有的类型别名配置。当我们的SQL映射文件被解析时,MyBatis会查找其中的<typeAlias>配置,并将找到的类型别名注册到这个注册中心。
  • 然后,在后续的解析过程中,每当MyBatis遇到一个类型时,它会首先检查TypeAliasRegistry是否存在该类型的别名,如果存在则使用该别名,否则使用全限定名。

所以,TypeAliasRegistry的作用就是用来保存类型别名配置,并让MyBatis在需要时可以查找并使用这些别名。它实现了MyBatis的类型别名功能。

TypeAliasRegistry作为MyBatis的核心组件之一,主要有以下作用:

  1. 保存类型别名配置:MyBatis可以在其中注册从映射文件中解析得到的类型别名,以备后续查找和使用。
  2. 查找别名:在MyBatis的解析过程中,每当需要一个类型时,MyBatis会首先在TypeAliasRegistry中查找该类型的别名。如果存在,则使用别名,否则使用全限定名。
  3. 简化配置:通过类型别名,可以简化MyBatis的映射配置。我们无需在每次使用一个类型时都输入其完整的限定名,只需要使用MyBatis为其配置的别名即可,这提高了配置的可读性和效率。
  4. 减少解析次数:每次MyBatis使用一个别名而非全限定名,可以减少一次对那个包的解析,这可以稍微提高MyBatis的解析性能。

配置元素

Configuration 配置信息来源于xml和注解,每个文件和注解都是由若干个配置元素组成,并呈现嵌套关系,总体关系如下图所示:在这里插入图片描述

在这里插入图片描述

关于各配置的使用请参见官网给出文档:https://mybatis.org/mybatis-3/zh/configuration.html#properties
在这里插入图片描述

元素承载

无论是XML还是我注解这些配置元素最弱都要被转换成JAVA配置属性或对象组件来承载。其对应关系如下:

  • 全配置(config.xml) 由Configuration对象属性承载
  • sql映射<select|insert...>@Select 等由MappedStatement对象承载
  • 缓存<cache..>@CacheNamespace 由Cache对象承载
  • 结果集映射 由ResultMap 对象承载
    在这里插入图片描述

配置文件解析

XML文件解析流程

配置文件解析需要我们分开讨论,首先来分析XML解析过程。xml配置解析其底层使用dom4j先解析成一棵节点树,然后根据不同的节点类型与去匹配不同的解析器。最终解析成特定组件。

解析器的基类是BaseBuilder 其内部包含全局的Configuration 对象,这么做的用意是所有要解析的组件最后都要集中归属至Configuration。接下来了解一下每个解析器的作用:

  • XMLConfigBuilder :解析config.xml文件,会直接创建一个Configuration对象,用于解析全局配置 。
  • XMLMapperBuilder :解析Mapper.xml文件,内容包含 等
  • MapperBuilderAssistant:Mapper.xml解析辅助,在一个Mapper.xml中Cache是对Statement(sql声明)共享的,共享组件的分配即由该解析实现。
  • XMLStatementBuilder:SQL映射解析 即<select|update|insert|delete> 元素解析成MapperStatement。
  • SqlSourceBuilder:Sql数据源解析,将声明的SQL解析可执行的SQL。
  • XMLScriptBuilder:解析动态SQL数据源当中所设置 SqlNode脚本集。

在这里插入图片描述

整体解析流程是从XmlConfigBuilder 开始,然后逐步向内解析,直到解析完所有节点。我们通过一个MappedStatement 解析过程即可了解到其整体解析流程。

在这里插入图片描述

流程说明:

  • 【XmlConfigBuilder】 接收一个config.xml 输入流,然后创建一个空Configuration对象
    在这里插入图片描述

  • 【XmlConfigBuilder】解析全局配置
    在这里插入图片描述

  • 【XmlConfigBuilder】mapperElements解析,通过Resource或url 指定mapper.xml文件

    • 【XmlMapperBuilder】解析缓存、结果集配置等公共配置
    • 【XmlMapperBuilder】解析Sql映射<select|insert|upate|delete>
      • 【XMLScriptBuilder】解析生成SQL数据源,包括动态脚本
    • 【XmlMapperBuilder】构建Statement
      • 【MapperBuilderAssistant】设置缓存并添加至Configuration

注解配置解析

注解解析底层实现是通过反射获取Mapper接口当中注解元素实现。有两种方式:

  • 一种是直接指定接口名
  • 一种是指定包名然后自动扫描包下所有的接口类

这些逻辑均由Mapper注册器(MapperRegistry)实现。其接收一个接口类参数,并基于该参数创建针对该接口的动态代理工厂,然后解析内部方法注解生成每个MapperStatement 最后添加至Configuration 完成解析。

在这里插入图片描述

想了解更多可参考文章:
MyBatis 核心配置综述之 Configuration详解
Mybatis主配置—Configuration

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

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

相关文章

react---react router 5 基本使用

目录 1.路由介绍 2.路由使用 3.路由组件和一般组件 4.Switch 单一匹配 5.解决二级路由样式丢失的问题 6.路由精准匹配和模糊匹配 1.路由介绍 路由是根据不同的 URL 地址展示不同的内容或页面&#xff0c;在 SPA 应用中&#xff0c;大部分页面结果不改变&#xff0c;只改变…

PostgreSQL 对特定类索引的优化,节省磁盘空间百倍 --BRIN 索引应用在生产案例...

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

为生信写的Python简明教程 | 视频5

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

Pytorch教程:Autograd基础

PyTorch的Autograd特征可以让PyTorch灵活快速的构建机器学习项目。autograd可以实现快速和容易的多重偏微分&#xff08;梯度&#xff09;计算。偏微分计算时反向传播神经网络学习的核心。 autograd的可以在运行时动态追踪计算&#xff0c;这意味着如果模型有决策分支、或者有…

linux 系统服务管理

目录 一、chkconfig 1、列出服务列表 chkconfig --list 2、关闭开启服务 chkconfig 服务名 on/off 3、添加新服务 chkconfig --add 服务文件名 4、删除已有服务 chkconfig --del 服务名 5、系统级别定义&#xff1a; 一、chkconfig chkconfig——centos…

Python学习46:分配学号(python123)

类型&#xff1a;列表元组‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬ 描述‪‬…

【Java项目】多种方式解决SpringBoot中遇到的控制台中文乱码问题

文章目录 配置JVM参数配置maven参数配置Runner配置Encoding通过配置文件 配置JVM参数 -Dfile.encodingUTF-8配置maven参数 重点就是 <configuration><fork>true</fork><jvmArguments>-Dfile.encodingUTF-8</jvmArguments></configuration>…

Linux常用命令——git命令

在线Linux命令查询工具 git 是目前世界上最先进的分布式版本控制系统 补充说明 git命令很多人都知道&#xff0c;Linus在1991年创建了开源的Linux&#xff0c;从此&#xff0c;Linux系统不断发展&#xff0c;已经成为最大的服务器系统软件了。 Linus虽然创建了Linux&#x…

线程池最佳实践

文章目录 yml参数配置定义参数实体bean配置线程池实战线程池高级理论线程池工作流程概述线程池拒绝策略线程池参数设置原则1&#xff09;如何为线程池设置合适的线程参数&#xff1f;2) 如何获取当前服务器的cpu核数&#xff1f;3) 无界队列问题 yml参数配置 # 定时任务线程池…

Spring高手之路1——深入理解与实现IOC依赖查找与依赖注入

本文从xml开始讲解&#xff0c;注解后面给出 文章目录 1. 一个最基本的 IOC 依赖查找实例2. IOC 的两种实现方式2.1 依赖查找&#xff08;Dependency Lookup&#xff09;2.2 依赖注入&#xff08;Dependency Injection&#xff09; 3. 在三层架构中的 service 层与 dao 层体会依…

Kafka与消息队列的比较

消息队列&#xff08;Message Queues&#xff09;是一种允许分布式系统和应用异步通信的服务。异步通信意味着消息发送者在等待接收者接收消息之前不需要等待&#xff0c;这可以提高性能和可扩展性&#xff0c;使应用能够并行处理消息。消息队列通过将消息存储在队列中来工作。…

【Vue_项目搭建部署】VUE快速入门——部署_安装ele等

检查是否安装 node npm npm -v node -v 全局安装yarn npm install -g yarn 安装完后&#xff0c;可以配置yarn的淘宝镜像 yarn config get registry //查看当前配置的镜像源 //https://registry.yarnpkg.com yarn config set registry http://registry.npm.taobao.or…

【Redis29】Redis进阶:缓存穿透、击穿与雪崩

Redis进阶&#xff1a;缓存穿透、击穿与雪崩 其实啊&#xff0c;这个内容本来不打算写了&#xff0c;网上讲这一块的内容实在是太多了。不过呢&#xff0c;本着学习还是要全面的原则&#xff0c;而且还要让自己多多巩固复习的原则&#xff0c;咱还是来写一道吧。 同样的&#x…

把钢铁侠战衣交给Z世代,没想到联想商用PC可以这么炫酷!

在数字化转型成为全球政企战略性与常态化诉求的今天&#xff0c;没有人会怀疑新一代数字技术和工具的重要性。 千行百业需要拥有全新的工具握力&#xff0c;也带动了商用 PC的市场需求不断被激发&#xff0c;产品升级迭代速度加快&#xff0c;成为PC行业最具发展机遇的市场。 从…

【Python】Python进阶系列教程--Python AI 绘画(二十)

文章目录 前言Windows 环境安装Civitai 介绍 前言 往期回顾&#xff1a; Python进阶系列教程-- Python3 正则表达式&#xff08;一&#xff09;Python进阶系列教程-- Python3 CGI编程&#xff08;二&#xff09;Python进阶系列教程-- Python3 MySQL - mysql-connector 驱动&a…

好几位朋友最近被迫创业!

见字如面&#xff0c;我是军哥&#xff01; 最近好几位朋友被迫创业&#xff0c;有程序员也有之前做业务的朋友&#xff0c;问其原因&#xff0c;都说现在找工作比较难&#xff0c;想想还是自己干吧。 对于这样的回答&#xff0c; 我表示非常的担心&#xff0c;因为风险实在是太…

VMIX如何RTMP推流给灵派编码器

本文链接&#xff1a;https://blog.csdn.net/weixin_45326556/article/details/131181058 第三方设备&#xff08;例如vMix&#xff0c;OBS&#xff09;如何RTMP推流给灵派编码器 1. 灵派编码器内置RTMP-SERVER2. 其他设备RTMP推流给灵派编码器方法3. 如何使用第三方推上来的RT…

Linux---ln命令、date命令

1. 链接命令ln ln&#xff08;link files&#xff09;命令的功能是为某一个文件在另外一个位置建立一个同步的链接。 当需要在不同的目录&#xff0c;用到相同的文件时&#xff0c;不需要在每一个目录下都放一个相同的文件&#xff0c;只需要在 某个固定目录&#xff0c;放上…

以正式员工身份从京东出来,又通过外包回去了,不甘心啊!

人生是一个圈&#xff0c;职场也是一个圈&#xff0c;一位京东员工就以实际行动诠释了这个“圈”&#xff1a; 以正式员工身份从京东出来&#xff0c;又通过外包回去了&#xff0c;不甘心啊&#xff0c;但外面找工作是地狱级难度&#xff01; 网友纷纷表示“笑死”、“有被笑到…

基于最小费用流(MCF)法的相位解包裹理论与实验验证-含Matlab代码

一、引言 最小费用流算法(Minimum cost flow, MCF) 最早是由 Costantini M. A1998 年提出的&#xff0c;该方法是将未解缠相位的相邻梯度差与解缠相位的相邻梯度差间的差异即不连续性最小化&#xff0c;具有极强鲁棒性与准确性&#xff0c;有基于规则与不规则网络之分。2002年…