《MyBatis技术内幕》笔记2—核心处理层

        因为该文主要是看书的笔记(当然自己看书时也会看源码并跟踪调试),所有没有详实的源码分析,但是可以作为源码分析的流程、索引和注释。

二、核心处理层

1、Mybatis初始化
    Mybatis初始化过程中,除了会读取mybatis-config.xml配置文件以及映射配置文件,还会加载配置文件指定的类,处理类中的注解,创建一些配置对象,最终完成框架中各个模块的初始化。
相关模式:建造者模式。
SqlSessionFactoryBuilder.build():初始化入口,会创建XMLConfigBuilder(继承BaseBuilder),包含了Configuration(几乎全部的配置信息)、typeAliasRegistry(定义的别名)、typeHandlerRegistry(自定义的jdbc类型与java类型的转换)。
XMLConfigBuilder.parse():解析mybatis-config.xml配置文件的入口,在里面解析到mappers标签时就会去加载一个个mapper.xml并解析。
XMLMapperBuilder.parse():解析mapper.xml映射文件的入口,完成命名空间与mapper接口绑定、解析ResultMap等,在解析sql节点时会交由XMLStatementBuilder负责。由于解析一个节点时会引用后面还未解析的节点,所以解析主要分两次,第一次解析configurationElement()会根据未解析的引用创建不同的*Resolver,并添加到Configuration的不同incomplete*集合中,然后第二次解析就是处理不同incomplete*,最后完成解析。
XMLStatementBuilder.parseStatementNode():是解析sql节点的入口,最后会被解析成MappedStatement对象。

2、SQL解析SqlSource与SqlNode
相关模式:组合模式。
OGNL表达式:用于方便获取${对象.属性}、标签中"属性!=null"等里面的表达式对应的值,在SqlNode中就会使用Ognl获得对应实参的值。
SqlSource接口:sql节点中的sql语句会被解析成对应的SqlSource对象,当然SqlSource对象是存在MappedStatement对象中的。在调用执行mapper接口时,会根据全局的配置、传入的参数获得带?的实际sql(即确定了<if>等节点的文本)和参数集(按?顺序对应),这里还没有把实参绑定到sql语句上。
SqlNode接口:sql语句中的定义的动态sql节点、文本节点等又会被解析成不同的SqlNode对象,使用组合模式组合成一个SqlNode,当然SqlNode对象是存在SqlSource中的。
DynamicSqlSource:实现SqlSource接口,负责处理动态语句,包括一个全局配置Configuration和SqlNode。其中SqlNode的实现是MixedSqlNode。
RawSqlSource:实现SqlSource接口,负责处理静态语句,只包含一个SqlSource。
StaticSqlSource:实现SqlSource接口,DynamicSqlSource和RawSqlSource最终都会将处理后的sql语句封装成StaticSqlSource对象。包含Configuration、parameterMappings和sql字符串(例如insert into tableName (column1,column2,column3) values (?,?,?))。
MixedSqlNode:实现SqlNode接口,由多个SqlNode的组合。如果sql语句中有if标签,那么MixedSqlNode中就含有IfSqlNode,如果有foreach标签,那么就含有ForEachSqlNode,其它文本语句就对应StaticTextSqlNode。

3、结果集映射ResultSetHandler
ResultSetHandler接口:负责映射select语句查询得到的结果集,还会处理存储过程执行后的输出参数。用户可以实现该接口,自定义处理结果集。
ResultSetHandler.handleResultSets():处理结果集入口,生成相应的结果对象集合。主要分两次处理,第一次处理MappedStatement.resultMaps中对应的结果集,如果处理中发现某个属性(结果集中的嵌套映射)涉及未解析的结果集,则把对应的ResultMapping放入nextResultMaps中,第二次处理就是根据nextResultMaps处理嵌套映射,完善结果集。
ResultSetHandler.handleRowValuesForSimpleResultMap():对于非嵌套的简单映射最终会由该方法处理,包括定位到指定的结果行、检测处理行数超限制和是否还有要处理的结果行、解决discriminate标签得到最终resultMap映射、执行映射得到结果对象(这里就会处理嵌套)、保存结果对象。
ResultSetHandler.handleRowValuesForNestedResultMap():对于嵌套映射最终会由该方法处理。
上面的嵌套可能说的有问题,嵌套的处理个人觉得太复杂,但平时基本没用嵌套,所以没有继续深究。

4、SQL执行Executor与StatementHandler
相关模式:模板方法模式、装饰器模式。
Executor接口:是mybatis核心接口之一,其中定义了数据库操作的基本方法(最终由StatementHandler执行),这些方法有些执行步骤是相同的,所以可以使用模板方法模式。
BaseExecutor抽象类:实现了Executor接口,实现了大部分方法,其中就使用了模板方法模式,它主要提供了缓存管理和事务管理的基本功能。继承BaseExecutor的子类只需要实现四个基本方法来完成数据库的相关操作即可。
一级缓存:BaseExecutor中提供的缓存是一级缓存,是会话级别的缓存。
CachingExecutor:是一个Executor装饰器,它为Executor对象增加了二级缓存的相关功能。
二级缓存:是应用级别的缓存,可在mybatis-config.xml文件中配置。
StatementHandler接口:是mybatis核心接口之一,完成了最核心的工作,如创建Statement对象、为sql语句绑定实参、执行sql语句、将结果集映射成结果对象。
ParameterHandler接口:DefaultParameterHandler实现类,完成sql语句与实参的绑定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值