mybatis 不等于空字符串_Mybatis源码分析(五):核心流程

50d5df7ab1a11f8cab7c92aa1f2bac51.png

Mybatis的初始化 建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式,属于创建型模式,它提供了一种创建对象的最佳方式。

Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建;

ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例;

Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息, 只负责保证对象各部分完整创建或按某种顺序创建;

Product:要创建的复杂对象

20fff8b80fc0ce8c6cd224fbb8a06ba1.png

与工厂模式区别

对象复杂度

建造者建造的对象更加复杂,是一个复合产品,它由各个部件复合而成,部件不同产品对象不同,生成的产品粒度细;

在工厂方法模式里,我们关注的是一个产品整体,无须关心产品的各部分是如何创建出来的;

客户端参与程度

建造者模式,导演对象参与了产品的创建,决定了产品的类型和内容,参与度高;适合实例化对象时属性变化频繁的场景;

工厂模式,客户端对产品的创建过程参与度低,对象实例化时属性值相对比较固定;

建造者模式的使用场景

1、需要生成的对象具有复杂的内部结构,实例化对象时要屏蔽掉对象内部的细节,让上层代码与复杂对象的实例化过程解耦,可以使用建造者模式;简而言之,如果“遇到多个构造器参数时要考虑用构建器”;

2、一个对象的实例化是依赖各个组件的产生以及装配顺序,关注的是一步一步地组装出目标象,可以使用建造器模式;

34f370bb37223d41cb87bb3413735ce1.png

XMLConfigBuilder: 主要负责解析mybatis-config.xml;

XMLMapperBuilder: 主要负责解析映射配置文件;

XMLStatementBuilder: 主要负责解析映射配置文件中的SQL节点;

093f746a87a149705fd9c671b2eaef18.png

mybatis-config.xml是如何加载到Configuration对象中的。

Configuration : Mybatis启动初始化的核心就是将所有xml配置文件信息加载到Configuration对象中, Configuration是单例的,生命周期是应用级的,看类的属性熟悉吗?就是配置文件mybatis-config.xml里可以配置的那些信息

83fda88053dd192bcc0ae4053d6efec0.png

话说回来,看是如何加载mybatis-config.xml的

4ab590c400d0de59217356f82620f3ec.png

那么跟一下SqlSessionFactoryBuilder对象的build方法,参数只有一个inputstream。

看这个是new XmlConfigBuilder 对象,说明利用这个对象的parse()方法先解析

ae8f0d7b172ad2de2c404161abe51684.png

然后看是如何解析的,跟进parse()方法:

8b82948b32e3524c52c54f024921e601.png

这个“/configuration”字符串是什么意思?就是mybatis-config.xml的根目录

<configuration>

</configuration>

解析这个中间的标签,就是下图这种

ebf878395e2ee676b79eaab416c013b7.png

那么再看:

52ef2130cda2f2c551c6f0981458a824.png
说白了就是由不同的函数去解析不同的标签。

随便挑几个看一下 properties,里面可以配置很多吧 可以配resource,url等

37c8a8d4f00b372ff1f334d284c91351.png

mappers里面也可以配很多吧 package class resource name 等

6d1bd157de0dcd25c45f2d5ec957fe41.png

看上图的这段代码:

26ec1c0ae2f8238f0ed83703ad6587de.png

如果mappers里的mapper的resource不为空,那么就去解析,使用 XMLMapperBuilder。XMLMapperBuilder: 主要负责解析映射配置文件;看下怎么解析的,跟进去parse(),注意这里是解析实体类对应的xml文件,下图字符串“/mapper”是xml的根节点,在这个根节点下是写sql标签的,还写resultMap的。

51dd3ed29cbef1149b4b8529a8d9fa1f.png

那就继续跟if下面这句代码咯,configurationElement()

7dac00884a2c4a046e324d6656a11f80.png

但是并没有看到建造者模式有什么应用呢?别急,继续看上图cacheElement(context.evalNode("cache"))这段代码:

a2db41af0a67630f3b679075df5c7501.png

继续跟红框的方法:(builderAssistant是下图这个类的对象)

4edd0766015e93f44847cf74888c5227.png

d7e3273ab047044bb6414aea40986cbb.png

上图build出来之后是要放到configuration里去的。

下图是CacheBuilder的字段

9f1d2c968ba4048c0f49fb60acebda1c.png

build()方法

32dfd157a249351247927fb122ed16ef.png

4d3eeea9703b6c15eb0ec2ba333aac1e.png

分析这个方法之前,看一下一个图:

4b5ef714a9d17d18df631c4b8fee054a.png

是怎么加载到configuration对象里的呢?

首先在configuration对象里看一下:

458bed7dd79377392bf3de19dda2e9e4.png

那就看value = resultMap这个类:

xml中的每一个resultMap都对应一个resultMap类

f3b33b43cd5ec90688cfbbae35a208d6.png

看上图中 List<ResultMapping> 泛型这个类。

77c0a11e8f2304fa6ad8e89740889dca.png

然后具体看代码

74e62a4d22612a8d8710f3058dc1e17c.png

上图的resultMapElements()

3e0bed477f6e1bd430ff9a043aca1ef1.png

a95d534e7d6872b8d82639fe91442093.png

63c224ec3ac4ab948897817a8eacf1bf.png

看上图的296行代码add()里面的new对象

32cde819d0246568a23463ba96040e14.png

62ed347e7f08daedef7aa027319271cc.png

继续跟上图的红框

2e23e4f4daa246a4413ec6f90d9cf38e.png

5ccfac4500d0bc0400499dc81f8641b2.png

add()之后完毕

fad5d869cba2725525dce44eeb169599.png

剩下的其实也没啥就是读取.xml所有的的resultmap,然后塞到configuration对象里去。


下来就是解析sql语句了:

02c9cbe645dfc86ea075f3b43d8c76d9.png

那么sql语句解析是:XMLStatementBuilder

62c67bfdba03c6eeaee7bbfc56535e0e.png

sql语句解析的时候中级目标是mappedStatment

MappedStatement:用于存储mapper.xml文件中的select、insert、update和delete节点,同时还包含了这些节点的很多重要属性;

56349781b3a953ac84e8e2a00328570e.png

a348708da2fb4ebede967e0365654159.png

具体看红框

262bd8bd372cccf001b5af8ae22f1b8e.png

那么初始化

c3cbfae573bb2069e00538f91c3486a6.png

再看一下下图红框

f824ed7806826fed71ce274c13b50489.png

SqlSource:mapper.xml文件中的sql语句会被解析成SqlSource对象,经过解析SqlSource包含的语句最终仅仅包含?占位符,可以直接提交给数据库执行

跟进去:

cf62ed9c72c7ef0acb71bfa315c90e6d.png

dcb24058e4d3767d0bbace7a8994c8d1.png

那具体来看一下是怎么解析sql语句的:

首先还是回到

26548365966da9cb58874831c160d9f6.png

c39bb7642fe3ab7ca8726551e7a1c8a2.png

直接看这个parseStatementNode()

c84d96ea43aae0b6ec1d3cf823124bec.png

03542d3c9d1e3003a48ae1c51bd21645.png

这个调用的意思就是 把xml中的sql语句封装成SqlSource

db732640daebd65d28151bd0af74448f.png

再跟实现类:建造者模式:

6f22b27041d54f805e351bbc49f0c868.png

e224c87f7c14e3f0030f655c0a1ad973.png

将SqlSource创建交给了XMLScrpitBuilder。根据是否是动态的语句,创建DynamicSqlSource或是RawSqlSource对象,并返回

上图方法第一句代码

eaf035446d9c22cd44a67a3691b80de9.png

MixedSqlNode是SqlNode的一个实现,包含了各个子节点,用来遍历输出子节点。SqlNode还有很多不同的实现,分别对应不同的节点类型。对应关系如下:

bf636d8de6eee1702c856689031b94dd.png

跟进去这个方法

88bc14a0bea0db507b2d6450e810669c.png

就跟到这个,往下不跟了,很麻烦


总之红框很重要

5f2e19be8d9465108f746d6d4e1e1181.png

那么到现在就是已经解析了cache、resultMap、curd。

fb4597e3c1f832424e04c895e1819151.png

4766fa9fe3ebc11d326d2bba3ca3a930.png

映射器的关键类

Configuration : Mybatis启动初始化的核心就是将所有xml配置文件信息加载到Configuration对象中, Configuration是单例的,生命周期是应用级的;

MapperRegistry:mapper接口动态代理工厂类的注册中心。在MyBatis中,通过mapperProxy实现 InvocationHandler接口,MapperProxyFactory用于生成动态代理的实例对象;

ResultMap:用于解析mapper.xml文件中的resultMap节点,使用ResultMapping来封装id,result等子元素;

MappedStatement:用于存储mapper.xml文件中的select、insert、update和delete节点,同时还包含了这些节点的很多重要属性;

SqlSource:mapper.xml文件中的sql语句会被解析成SqlSource对象,经过解析SqlSource包含的语句最终仅仅包含?占位符,可以直接提交给数据库执行;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值