首页 > 编程笔记 > Java笔记

组合模式在MyBatis源码中的应用

本节主要介绍组合模式在 MyBatis 中一个非常经典的案例。

MyBatis 在解析各种 Mapping 文件中的 SQL 语句时,涉及了一个非常关键的类叫作 SqlNode。XML 中的每一个 Node(节点)都会被解析为一个 SqlNode 对象,最后把所有 SqlNode 都拼装到一起,就成为了一条完整的 SQL 语句。例如以下我们经常用到的动态 SQL 语句。
<select id="getStudent" parameterType="long" resultType="com.entity.Student">
    select id,name,age from student
    <where>
        <if test="id!=null and id != ''">
            AND id=#{id}
        </if>
    </where>
</select>
SqlNode 的源码如下:
public interface SqlNode {
    boolean apply(DynamicContext context);
}
SqlNode 是所有动态节点都实现的接口,它会根据传入的参数 context 解析该 SqlNode 记录的 SQL 语句片段,并调用 DynamicContext.appendSql( ) 方法将解析后的 SQL 语句片段追加到 DynamicContext 的 sqlBuilder 中保存。当所有 SqlNode 都完成解析时,可以通过 DynamicContext.getSql( ) 获取一条完整的 SQL 语句。

DynamicContext 类中部分源码如下:
public class DynamicContext {
    ...
    public void appendSql(String sql) {
        this.sqlBuilder.append(sql);
        this.sqlBuilder.append(" ");
    }

    public String getSql() {
        return this.sqlBuilder.toString().trim();
    }
    ...
}
TextSqlNode 类中实现的 apply( ) 方法如下:
public boolean apply(DynamicContext context) {
    GenericTokenParser parser = this.createParser(new TextSqlNode.BindingTokenParser(context, this.injectionFilter));
    context.appendSql(parser.parse(this.text));
    return true;
}
以上我们只列出了 TextSqlNode 类实现 apply( ) 的部分代码,对其它源码实现感兴趣的小伙伴可以去研究一下,这里给大家展示一下类图,如下图所示。

SqlNode类图

所有教程

优秀文章