Mybatis源码研究之SqlSource
来源:互联网 发布:quickconnect 域名 编辑:程序博客网 时间:2024/04/28 15:39
Mybatis中少有的有注释的接口
1. SqlSource
接口
/** * Represents the content of a mapped statement read from an XML file or an annotation. * It creates the SQL that will be passed to the database out of the input parameter received from the user. * * @author Clinton Begin */ // 以上注释就不作翻译了.public interface SqlSource { BoundSql getBoundSql(Object parameterObject);}
2. 继承图
SqlSource StaticSqlSource // SqlSource实例的直接构造者就是 SqlSourceBuilder, 而SqlSourceBuilder中的parse方法所返回的是StaticSqlSource实例. RawSqlSource // ProviderSqlSource DynamicSqlSource
Mybatis中非常重要的
MappedStatement
类中就有一个sqlSource
字段.SqlSource
实例的直接构造者就是SqlSourceBuilder
, 而SqlSourceBuilder
所返回的则是StaticSqlSource
实例(SqlSource
的实现者之一). 而SqlSource
接口的其他三个实现者(RawSqlSource
,DynamicSqlSource
,ProviderSqlSource
)无一例外地都重度依赖于SqlSourceBuilder
.SqlSourceBuilder
类也继承了BaseBuilder
, 相比较继承自BaseBuilder
的其他XMLXxx来说, 这个类在语义上相当突兀. XMLXxxx是我们读Mybatis源码时最先会接触到的代码, 它们就是负责解析配置文件的. 所以我们会顺理成章地猜测继承BaseBuilder
来解析XML配置文件. 而SqlSourceBuilder
是为了复用BaseBuilder
的功能.DynamicSqlSource
里的主要逻辑, 参见 MyBatis源码研究之$和# 中的补充说明
部分.
3. BoundSql
接口
关于这个请参见本人的另外一篇博客
Mybatis源码研究之BoundSql
4. LanguageDriver
接口
- 该接口也是构造返回
SqlSource
的方法. - 而且其子类
XMLLanguageDriver
(这个类也是Mybatis默认使用的LanguageDriver
实现者)中有个细节就是,其createSqlSource
方法中的
script = PropertyParser.parse(script, configuration.getVariables());
这样一行代表着 如果编写的映射语句中如果有${ }
形式 会使用configuration.getVariables()
中定义的变量预替换一次, 而且查看PropertyParser
类中的内部子类VariableTokenHandler
, 它只会换已有变量,对于没有的, 它会原样返回 :return "${" + content + "}";
5. SqlSourceBuilder
类
- 该类的确切位置是在
org.apache.ibatis.builder.SqlSourceBuilder
org.apache.ibatis
作为Mybatis的根package,我们不需要关心这个.- 作为Mybatis的顶级package之一的builder 主要负责的是对xml配置文件的解析工作,而作为其中一员的
SqlSourceBuilder
自然不能免俗。- 首先看名字就知道它关联到了
SqlSource
接口;而这个SqlSource
接口的唯一方法返回的是BoundSql
- 其次这个类唯一的public方法
parse
,一眼看上去就是根据程序员提供的原始的sql语句,以及其他几个参数; 来构建出最终的SqlSource
.
- 首先看名字就知道它关联到了
- 在查找对其parse的调用时,我们可以看到
DynamicSqlSource
类中有对其的使用,而DynamicSqlSource
正好就是实现了SqlSource
接口.
在DynamicSqlSource
实现的getBoundSql
方法中,我们可以看到对于在Mybatis的xml书写时,为啥parameterType
的内容被无视,就是因为其对parameter type的选择最终还是基于实际的parameterObject的实际类型. - 在
SqlSourceBuilder
的内部类ParameterMappingTokenHandler
的私有方法buildParameterMapping
中我们可以看到- 看名字就知道这个方法是用来构建一个
ParameterMapping实例
的.而ParameterMapping类就是封装了程序员所书写的#{ }
中的所有内容. - 对
#{ }
中各种参数的相应处理 - 目前的可用的参数如下
javaType
,jdbcType
,mode
,numericScale
,resultMap
,typeHandler
,jdbcTypeName
- 例子如下:
#{middleInitial, mode=OUT, jdbcType=STRUCT, jdbcTypeName=MY_TYPE, resultMap=departmentResultMap}
- 对于这一部分,可以看看MyBatis官方文档中的 >>Mapper XML文件 >> Parameters小节.
- 所以可以猜测到: 这些属性只能在
#{ }
,而不能在${ }
中使用.
- 看名字就知道这个方法是用来构建一个
6. ParameterMapping
类
- 虽然在xml映射文件编写时不再推荐使用
ParameterMapping
. 但在ParameterMappingTokenHandler
的实现里, 依然会将每个#{ }
里的内容解析为一个ParameterMapping
实例. - 这里补充一句: 每个
ParameterMapping
实例真正被使用的位置则是位于ParameterHandler
接口唯一的实现者DefaultParameterHandler
中的setParameters
方法中. 所以我们在使用JDBC编程时进行的PreparedStatement.setXXX
操作其实是在每个TypeHandler<T>
接口的实现类中完成的.
//TypeHandler<T>的使用位置: `DefaultParameterHandler`类中的第77行 (Mybatis-3.2.2.jar)typeHandler.setParameter(ps, i + 1, value, jdbcType);
7. ParameterExpression
类
在SqlSourceBuilder
的内部类ParameterMappingTokenHandler
中,其parseParameterMapping
方法中对ParameterExpression
类的使用
1. 这个ParameterExpression
类封装了对#{ }
中内容的解析逻辑,
2. 而且其继承自HashMap<String, String>
,所以可以将解析的结果以键值对的方法存储起来.
3. 外界对其的调用直接以Map
的方式获取即可.
4. 所以在使用#{ }
中的内容得到一个ParameterExpression
实例之后, 就能直接使用Map
接口提供的方法调取用户在#{ }
设置的属性值了.
8. Links
- http://www.open-open.com/lib/view/open1363572227609.html
阅读全文
0 0
- Mybatis源码研究之SqlSource
- MyBatis源码分析之MappedStatemenet,SqlSource,DynamicContext
- MyBatis源码研究之$和#
- Mybatis源码研究之DynamicContext
- Mybatis源码研究之XMLScriptBuilder
- Mybatis源码研究之BoundSql
- Mybatis源码研究之Logger
- Mybatis源码研究序
- MyBatis源码研究-缓存
- Mybatis与Spring集成源码研究之MapperScannerConfigurer
- Mybatis源码研究2:框架整体设计
- Mybatis源码研究5:数据源的实现
- Mybatis源码研究6:元数据(metadata)
- Mybatis源码研究2:框架整体设计
- Mybatis源码研究5:数据源的实现
- Mybatis源码研究6:元数据(metadata)
- Mybatis源码研究2:框架整体设计
- Mybatis源码研究5:数据源的实现
- 315前夕,打假小程序“12315”上线
- WebService之jax-ws入门
- 【linux 学习】linux上的PhotoShop-Gimp(linux mint)
- 5. 1 IO流(字符流(6个),字节流(4个),(缓冲区装饰类(装饰设计模式)),(转换流))
- Javascript计算器(二)-简单的布局与美化
- Mybatis源码研究之SqlSource
- LaTex: 数学公式
- C++ 拷贝构造函数
- Codeforces-Bertown Subway(思维)
- 启动新进程之复制进程映像——fork系统调用
- Java数组的创建与初始化
- 电脑上不了Github的完整解决方法(亲测)
- 渲染管线理解4
- C语言知识点杂谈