Mybatis源码分析(1) - Mybatis关键类

作者: 疯狂小兵 | 2019-04-30 | 阅读
「编辑」 「本文源码」

参数解析

ParamNameResolver类用于解析接口方法中传递的参数

重要方法:getNamedParams

解析步骤:

  1. 如果没有参数,直接返回null
  2. 如果没有并且参数数量为1,则取第一个参数值
  3. 在有注解或者参数数量大于1的情况下,将参数转为Map形式,有注解的,map中的key为注解的value值,没有注解的使用参数顺序号,从0开始。且mybatis会自动生成参数名前缀为param的参数。
//key -> value
0 -> 123
1 -> 234
param0 -> 123
param1 -> 234

其中key=0和param0表示的同一个参数,两种key

ParameterMapping 为每个参数名称,参数类型的处理类。

ParameterMappingTokenHandler用于处理解析Sql中的占位符变量

方法体

org.apache.ibatis.mapping.MappedStatement类用于解析并xml文件中的每个方法标签中的Sql并将其转换为java中的代码格式。

主要结构包括

参数名 类型 功能 备注
configuration Configuration 整个mybatis所有配置信息类  
id 唯一指定该方法的id,为方法名或全限定方法名    
statementType StatementType Sql语句的类型,STATEMENTPREPAREDCALLABLE  
resultSetType ResultSetType 结果集类型。FORWARD_ONLYTYPE_SCROLL_INSENSITIVETYPE_SCROLL_SENSITIVE  
sqlSource SqlSource 内部结构为BoundSql BoundSql包含完整的Sql,含有类型信息的参数以及参数名和参数值的映射表
parameterMap ParameterMap 待补充描述  
resultMaps List 待补充描述  
sqlCommandType SqlCommandType Sql命令的类型。包括:INSERT, UPDATE,DELETE,SELECT,FLUSH  
keyGenerator KeyGenerator 主键生成的类。实现类有:SelectKeyGeneratorJdbc3KeyGeneratorNoKeyGenerator  
keyProperties String[] 指定key的属性,该属性为pojo的属性名  
keyColumns String[] 指定key的列,该属为表中的字段  
statementLog Log 指定的语句打印的日志类  
lang LanguageDriver 生成Sql的驱动器,实现类有:XMLLanguageDriverRawLanguageDriver。其中RawLanguageDriver是继承的XMLLanguageDriver,且不支持胴体Sql  

MappedStatement.getBoundSql通过传入的参数,完成Sql的解析和构建。

Sql解析

DynamicContext为主要的动态Sql的操作类

其中有参数bindings,结构为ContextMap,重写了hashMap的get方法。在实例化DynamicContext时会设置_parameter_databaseId两个key

SqlSourceBuilder会通过parse方法将原始Sql和绑定的参数进行解析,使用GenericTokenParser将初步解析出来的动态sql中的#{var}替换为?,并将对应的var通过ParameterMappingTokenHandler设置到ParameterMapping中。

Sql到这里已经解析完毕,可以将其转化为你静态Sql了,将解析后的sql赋给StaticSqlSource生成新对象

动态Sql的片段

在Mybatis中,初始化时会根据标签,将Sql代码片段解析到对应的SqlNode中,在实际执行时进行解析。

SqlNode集合

类型 功能 备注
MixedSqlNode 整个Sql语句的总的SqlNode 不具有实际的解析能力。是集合该sql下所有sql片段的地方。
StaticTextSqlNode 存储Sql中静态的文本Sql 只存储不解析
ForEachSqlNode 对应xml中的foreach标签。ForEachSqlNode内属性分别对应标签上的各属性。通过内部解析器ExpressionEvaluator将collect中指定的属性的值取出(采用OGNL方式)  
     
     
     
     
     
     
     

Session

DefaultSession为默认实现类

该类中有个比较重要的包装参数的方法:wrapCollection。对于Collection类型和数组类型的参数,会给转为Map,且key分别为listarray

总结

通过整理每个包的主要功能。通览整个mybatis的代码结构,了解各个组件的位置和大概的处理关系。为后续分析源码打下基础。

可能的问题

动态Sql每次请求都要重新解析一次,可能每次传入的参数不同,解析也就不同。

StatementHandler每个Session都需要重新建立实例


版权声明:本文由 在 2019年04月30日发表。本文采用CC BY-NC-SA 4.0许可协议,非商业转载请注明出处,不得用于商业目的。
文章题目及链接:《Mybatis源码分析(1) - Mybatis关键类》




  相关文章:

「游客及非Github用户留言」:

「Github登录用户留言」:

TOP