MyBatis 源码分析——动态SQL语句
有几年开发经验的程序员应该都有暗骂过原生的SQL语句吧。因为他们不能一句就搞定一个业务,往往还要通过代码来拼接相关的SQL语句。相信大家会理解SQL里面的永真(1=1),永假(1=2)的意义吧。所以mybatis动态SQL功能在笔者看来是最引吸人的。为了更好的区别XML映射文件上的SQL语句。mybatis把SQL语句分为四类。那么这个笔者已经在前面的章节里面讲过了。但是我们在开发过程中常常用到的也就俩种:静态和动态。
关于静态和动态的定义,笔者是这样子理解的——静态SQL语句显示就是里面没有相关的罗辑。即是没有#if之类的语活。反之则是动态SQL语句。而笔者感兴趣是动态SQL部分。我们都知道在读取XML映射文件信息的时候就会分析当前的SQL语句属于哪一种类型。这部分工作就是放在源码的XMLScriptBuilder类里面。
public SqlSource parseScriptNode() {
List<SqlNode> contents = parseDynamicTags(context);
MixedSqlNode rootSqlNode = new MixedSqlNode(contents);
SqlSource sqlSource = null;
if (isDynamic) {
sqlSource = new DynamicSqlSource(configuration, rootSqlNode);
} else {
sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);
}
return sqlSource;
}
看到了吧,是通过成员isDynamic的值来获取相关类型的SQL语句类。DynamicSqlSource类从字面上来讲就很容易看出来是属于动态的。而下面便是静态的。关键的部分还是在parseDynamicTags方法里面。
为了实现动态SQL语句的功能。mybatis设置几个动态的节点。如if,choose 等。当然如果你们想要知道有几个的话,最好跟笔者一样子点开他相关的DTD文件。如下
<!ELEMENT select (#PCDATA | include | trim | where | set | foreach | choose | if | bind)*>
我们可以看到include 、trim 、where 、set 、foreach 、choose 、if 、bind。各自的用法在官网上面有些详细的说明。 大家可以去看看。相信大家看到这里心里应该有了一定的想法。为了实现动态SQL,那么mybatis一定会根据不同的节点来做不同的逻辑处理。这也是笔者为什么说——关键的部分还是在parseDynamicTags方法里面。因为parseDynamicTags方法是用于分析当前select或是delete等节点的SQL节点(即是SqlNode类)。可以说终于生成的SQL语句就是靠这若干个SqlNode类提供生成的。在前面几章中我们有讲到关于BoundSql类的作用。在这里就一下明白了。如下图

通过parseDynamicTags方法分析出需要用到的若干个SqlNode类。并确定他是否是动态SQL语句。如果是,就创建DynamicSqlSource类。而DynamicSqlSource类会存放在MappedStatement类里面。当我们要通过BoundSql类来生成StatementHandler实例的时候,就会从通过MappedStatement类获得对应的BoundSql类。而BoundSql类的getSql方法就会我们最终的落点。
其实笔者的内心是有一点小失望的。我本以为mybatis会一直实现自己的元素处理。当然这只是笔者内心的一点完美主义吧。正如官网上讲的MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。所以我们可以源码里面看到ognl的应用。
Map<Object, OgnlClassResolver> context = Ognl.createDefaultContext(root, new OgnlClassResolver());
对于ongl笔者就不想多说了。有兴趣的读者们可以自己去看一下。笔者建议还是去看一下吧。struts2框架里面也用到他了。
关于mybatis系列笔者就记录到这里了。希望对大家有用。
MyBatis 源码分析——动态SQL语句的更多相关文章
- Spring mybatis源码篇章-动态SQL节点源码深入
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-动态SQL基础语法以及原理 前话 前文描述到通过mybatis默认的解析驱动类org.apache.ibat ...
- Spring mybatis源码篇章-动态SQL基础语法以及原理
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-Mybatis的XML文件加载 前话 前文通过Spring中配置mapperLocations属性来进行对m ...
- MyBatis 源码分析——动态代理
MyBatis框架是如何去执行SQL语句?相信不只是你们,笔者也想要知道是如何进行的.相信有上一章的引导大家都知道SqlSession接口的作用.当然默认情况下还是使用DefaultSqlSessio ...
- mybatis源码解读(五)——sql语句的执行流程
还是以第一篇博客中给出的例子,根据代码实例来入手分析. static { InputStream inputStream = MybatisTest.class.getClassLoader().ge ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- 精尽 MyBatis 源码分析 - MyBatis 初始化(三)之 SQL 初始化(上)
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - MyBatis初始化(四)之 SQL 初始化(下)
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽MyBatis源码分析 - SQL执行过程(四)之延迟加载
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- 精尽 MyBatis 源码分析 - SqlSession 会话与 SQL 执行入口
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
随机推荐
- linux下php开发环境搭建(nginx+php+mysql)
安装前准备工作 先安装一些必要的类库 yum install -y wget zlib-devel bzip2-devel curl-devel openssl openssl-devel vim ...
- MySQL账户管理
body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10 ...
- p1144一元三次方程求解
题目描述: 有形如:f(x)=ax^3+bx^2+cx+d=0这样的一元三次方程,给出该方程中各项的系数a,b,c,d,它们均为实数,并约定该方程一定存在着3个不同的实数解,解的范围在-100至100 ...
- Java多线程编程(四)—浅谈synchronized与lock
一.共享资源竞争问题 在Java语言的并发编程中,由于我们不知道线程实际上在何时运行,所以在实际多线程编程中,如果两个线程访问相同的资源,那么由于线程运行的不确定性便会在这种多线程中产生访问错误.所以 ...
- Html5 基础----列表详述
html5列表 标签 列表分为: 有序列表/无序列表/自定义列表,用的最多的为无序列表和自定义列表 1.有序列表(order list) eg:把
- 2015年ACM-ICPC亚洲区域赛合肥站网络预选赛H题——The Next (位运算)
Let L denote the number of 1s in integer D's binary representation. Given two integers S1 and S2, we ...
- maven项目无法查看方法
问题如图: 解决:
- html5常用英语单词
Aabsolute 绝对active 激活的align 对齐alpha 半透明度animation 卡通片绘制auto 自动aside 偏栏 Bbackground 背景bgcolor 背景颜色blo ...
- Git-多人协作
声明: 此文参考廖雪峰老师的官方网站知识总结http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017 ...
- python IP地址转16进制
python IP地址转16进制 第一种方法: 通过socket.inet_aton实现 import socket from binascii import hexlify ary='192.168 ...