MyBatis源码阅读 SqlSource创建流程


一、相关类及对象

二、流程图

MyBatis源码阅读 SqlSource创建流程

image

三、SqlSource创建流程

创建SqlSource,解析SQL,封装SQL语句(未参数绑定)和入参信息

@Override
    public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {
        // 初始化了动态SQL标签处理器
        XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);
        // 解析动态SQL
        return builder.parseScriptNode();
    }

初始化了动态SQL标签处理器

public XMLScriptBuilder(Configuration configuration, XNode context, Class<?> parameterType) {
        super(configuration);
        this.context = context;
        this.parameterType = parameterType;
        // 初始化动态SQL中的节点处理器集合
        initNodeHandlerMap();
    }

1.XMLScriptBuilder#initNodeHandlerMap

初始化动态SQL中的节点处理器集合

private void initNodeHandlerMap() {
        nodeHandlerMap.put("trim", new TrimHandler());
        nodeHandlerMap.put("where", new WhereHandler());
        nodeHandlerMap.put("set", new SetHandler());
        nodeHandlerMap.put("foreach", new ForEachHandler());
        nodeHandlerMap.put("if", new IfHandler());
        nodeHandlerMap.put("choose", new ChooseHandler());
        nodeHandlerMap.put("when", new IfHandler());
        nodeHandlerMap.put("otherwise", new OtherwiseHandler());
        nodeHandlerMap.put("bind", new BindHandler());
    }

解析动态SQL

public SqlSource parseScriptNode() {
        // 解析selectinsert updatedelete标签中的SQL语句,最终将解析到的SqlNode封装到MixedSqlNode中的List集合中
        // ****将带有${}号的SQL信息封装到TextSqlNode
        // ****将带有#{}号的SQL信息封装到StaticTextSqlNode
        // ****将动态SQL标签中的SQL信息分别封装到不同的SqlNode中
        MixedSqlNode rootSqlNode = parseDynamicTags(context);
        SqlSource sqlSource = null;
        // 如果SQL中包含${}和动态SQL语句,则将SqlNode封装到DynamicSqlSource
        if (isDynamic) {
            sqlSource = new DynamicSqlSource(configuration, rootSqlNode);
        } else {
            // 如果SQL中包含#{},则将SqlNode封装到RawSqlSource中,并指定parameterType
            sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);
        }
        return sqlSource;
    }

解析selectinsert updatedelete标签中的SQL语句,最终将解析到的SqlNode封装到MixedSqlNode中的List集合中。

protected MixedSqlNode parseDynamicTags(XNode node) {
        List contents = new ArrayList<>();
        //获取