【MyBatis详解】——动态SQL解析与执行原理

目录

  • Demo:动态SQL
  • 1. Xml中Sql节点解析——存储到SqlSource对象
  • 2. Sql执行——通过调用SqlSource.getBoundSql得到动态处理过的Sql
    • 1. SqlNode.apply处理动态内容
    • 2. SqlSourceParser.parse替换#符号为?

Demo:动态SQL

<select id="countByMap" resultType="int">
        select count(id) from person
        <where>
            <if test="id != null">
                AND id = #{id}
            </if>
            <if test="name != null">
                AND name = ${name}
            </if>
             <if test="description != null">
                AND description = #{description}
            </if>
        </where>
    </select>

传参Map:id=1,name=ss

1. Xml中Sql节点解析——存储到SqlSource对象

  • 在【MyBatis详解】——从Xml配置解析到SQL执行过程
    的配置解析——SQL解析阶段,
    XMLScriptBuilder调用了parseScriptNode方法:

  • 此SqlSource被解析为动态sql,所以为DynamicSqlSource类型;其rootSqlNode祖节点为MixedSqlNode类型,即一个3个子节点的数组:
    【MyBatis详解】——动态SQL解析与执行原理_第1张图片
    第1个子节点为静态sql类型:
    【MyBatis详解】——动态SQL解析与执行原理_第2张图片
    同样的第3个子节点为静态sql类型:
    【MyBatis详解】——动态SQL解析与执行原理_第3张图片
    关键看第2个子节点,为WhereSqlNode类型:
    【MyBatis详解】——动态SQL解析与执行原理_第4张图片
    在Where节点中,又包括了两个if标签的内容,都被保存为StaticTextSqlNode静态sql类型。

    • 注意此时的#和$符号都还没用被替换掉
    • if标签为true或者false的节点都被保存了下来
      【MyBatis详解】——动态SQL解析与执行原理_第5张图片

2. Sql执行——通过调用SqlSource.getBoundSql得到动态处理过的Sql

  • 在【MyBatis详解】——从Xml配置解析到SQL执行过程
    的Executor执行SQL阶段,在StatementHandler被创建的过程中,有一个getBoundSql的步骤:
    然后将调用上一步得到的SqlSource的getBoundSql方法:

1. SqlNode.apply处理动态内容

  • 解析if等动态标签,只有test条件为true时,才append对应sql
  • 把$符号替换为参数,直接拼接sql
    【MyBatis详解】——动态SQL解析与执行原理_第6张图片
  • SqlNode
    节点解析时的工具类,简单理解就是xml中的每个标签,如update,trim,if标签
    其实现类包括
    【MyBatis详解】——动态SQL解析与执行原理_第7张图片
    实现动态Sql的关键就是 各个SqlNode的 apply方法;
    以IfSqlNode为例,如果满足条件,则append标签中的内容,并返回true:
    【MyBatis详解】——动态SQL解析与执行原理_第8张图片
    而StaticTextSqlNode类型静态sql,则直接append
    【MyBatis详解】——动态SQL解析与执行原理_第9张图片

2. SqlSourceParser.parse替换#符号为?

【MyBatis详解】——动态SQL解析与执行原理_第10张图片
最终得到的是JDBC格式的SQL,实现动态Sql的关键是各个SqlNode的 apply方法。

你可能感兴趣的:(框架大集合,mybatis,java)