【12.MyBatis源码剖析与架构实战】12.SqlSource解析源码剖析-XML映射解析⽅式
MyBatis SqlSource 解析源码剖析(XML 映射解析方式)在 MyBatis 初始化阶段,XML 映射文件(Mapper XML)中的 SQL 语句会被解析成SqlSource对象,并最终封装到MappedStatement中,存储在Configuration里供运行时使用。本文将深入剖析XML 方式下SqlSource的解析过程,包括标签处理、SqlNode树构建和SqlSource创建。一、整体流程概览二、入口:XMLMapperBuilder 解析 Mapper 文件XMLMapperBuilder负责解析 Mapper XML 文件,其parse方法最终调用configurationElement来解析mapper根节点下的元素。// XMLMapperBuilder.configurationElementprivatevoidconfigurationElement(XNodecontext){try{Stringnamespace=context.getStringAttribute("namespace");builderAssistant.setCurrentNamespace(namespace);cacheRefElement(context.evalNode("cache-ref"));cacheElement(context.evalNode("cache"));parameterMapElement(context.evalNodes("/mapper/parameterMap"));resultMapElement(context.evalNodes("/mapper/resultMap"));sqlElement(context.evalNodes("/mapper/sql"));// 关键:解析所有 select/insert/update/delete 语句buildStatementFromContext(context.evalNodes("select|insert|update|delete"));}catch(Exceptione){thrownewBuilderException("Error parsing Mapper XML. Cause: "+e,e);}}buildStatementFromContext会为每个 SQL 节点创建一个XMLStatementBuilder,并调用其parseStatementNode方法。三、XMLStatementBuilder:解析 SQL 节点属性XMLStatementBuilder负责解析 SQL 节点的各种属性(如id、parameterType、resultMap等),并创建MappedStatement。publicvoidparseStatementNode(){Stringid=context.getStringAttribute("id");StringparameterType=context.getStringAttribute("parameterType");// ... 其他属性解析// 获取 LanguageDriver(可通过 @Lang 或全局配置覆盖)LanguageDriverlangDriver=getLanguageDriver(context);// 关键:创建 SqlSourceSqlSourcesqlSource=langDriver.createSqlSource(configuration,context,parameterTypeClass);// 构建 MappedStatement 并注册builderAssistant.addMappedStatement(...,sqlSource,...);}LanguageDriver默认是XMLLanguageDriver,它提供了createSqlSource方法,接受XNode参数。四、核心:XMLScriptBuilder 解析 SQL 内容XMLLanguageDriver.createSqlSource内部调用XMLScriptBuilder.parseScriptNode,将 SQL 节点内容转换为SqlSource。// XMLScriptBuilder.parseScriptNodepublicSqlSourceparseScriptNode(){MixedSqlNoderootSqlNode=