网站站外推广方法,西安网站建设设计,中国商标网商标查询官网查询,页面设计怎么设计上一篇分析了SqlSession执行sql的过程#xff0c;其中并没有分析sql是从哪里来的#xff0c;今天就来仔细分析下。Sql来源从上一篇的最后一步执行sql那里倒推sql的来源#xff0c;源码主要过程如下图#xff1a;可以看到最后是通过BoundSql直接获取的sql#xff0c;然后往…上一篇分析了SqlSession执行sql的过程其中并没有分析sql是从哪里来的今天就来仔细分析下。Sql来源从上一篇的最后一步执行sql那里倒推sql的来源源码主要过程如下图可以看到最后是通过BoundSql直接获取的sql然后往前倒推最后发现是通过MappedStatement的getBoundSql方法返回的。MappedStatement在之前分析mapper的时候知道一个执行sql对应一个MappedStatement对象它封装有mybatis中需要执行一条sql的所有信息所以从这里获取也是理所应当的。MappedStatement的getBoundSql方法那么就来看下MappedStatement的getBoundSql方法吧源码如下图首先是右边MappedStatement的getBoundSql方法这次改了下sql传递了两个参数但是对程序基本没什么影响。可以看到BoundSql是通过SqlSource创建的通过debug知道是DynamicSqlSource对象。左边是DynamicSqlSource的getBoundSql方法可以先看后面的创建BoundSql对象是通过SqlSource初始化的而创建SqlSource对象需要的第一个参数是通过context.getSql()得到的。而在getBoundSql方法第一步是初始化了context从上图的debug可以看到目前context的信息bindings属性已经通过初始化把参数设置进去而sqlBuilder还是一个空字符串。关键代码就在当前打断点的“rootSqlNode.apply(context);”这行代码。从上图可以看到rootSqlNode是一个MixedSqlNode对象MixedSqlNode对象的apply方法是遍历属性contents的所有元素并执行它们的apply方法可以看到contents只有一个TextSqlNode对象的元素。所以最终来到TextSqlNode对象。TextSqlNode对象的text属性保存的就是还没有进行处理的sql。TextSqlNode处理sqlTextSqlNode处理sql的源码如下图右侧是TextSqlNode的apply方法参数context就是上一步需要的context他里面包含有请求参数从上一张源码图可以知道它的属性sqlBuilder此时还是一个空字符串而apply就是去拼接sqlBuilder。apply方法首先创建了一个GenericTokenParser对象GenericTokenParser对象有三个属性openToken、closeToken、handler。其中openToken、closeToken分别对应字符串”${”、”}”而handler的属性context对应传递进来的contextinjectionFilter属性是TextSqlNode的injectionFilter。apply第二行代码“context.appendSql(parser.parse(text));”可以看出来parser.parse(text)就是生成sql的代码。其中text是TextSqlNode中没有处理的原始sql。所以sql生成在GenericTokenParser的parse方法parse方法的关键源码如上图左侧。主要步骤分析如下1、从sql找到第一个“${”位置start获取到元素sqltext的字符数组src2、把src从开始到start处的字符拼接到结果builder上也就是把“${”的内容拼接到结果上3、从start2的位置开始找“}”的位置end从src数组里取出“${”、“}”之间的字符组成字符串并根据字符串从hander中取出字符串对应的参数值。并把值拼接到结果builder上。最后还有一点代码没有截取到“start text.indexOf(openToken, offset); } while (start -1);”也就是第4步。4、继续找到下一个“${”并拼接。最终组成完整的sql。实际上GenericTokenParser的parse方法还是比较简单的就是把传递进来的参数text中openToken、closeToken中间的内容替换成对应的参数。总结从之前的分析我们知道一个MappedStatement对应一个sql那么如何从MappedStatement获取组装好的sql呢实际上是MappedStatement的属性sqlSource。而sqlSource实际上是依靠rootSqlNode在之前我们分析过解析mapper文件是把sql生成了嵌套的各种SqlNode子类。今天就看到他们的使用了。不过今天的算是比较简单的后面来一个稍微复杂一点的看看sql的解析过程。Java程序员日常学习笔记如理解有误欢迎各位交流讨论