SqlSource
构建动态SQL
//XMLStatementBuilder.parseStatementNode()
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
涉及类
- LanguageDriverRegistry+LanguageDriver
- XMLStatementBuilder
- SqlSource+SqlNode+SqlSourceBuilder
- MappedStatement
0、 解析Statement中一些重要点
- SqlSource如何构建?
- Sql语句中如“#{xxx}”和“${xxx}‘如何处理?
- SqlNode是如何创建的?
1、LanguageDriverRegistry+LanguageDriver
在初始化Configuration时,会预先初始化MyBatis提供的两个LanguageDriver的实现类并注册到LanguageDriverRegistry
中:RawLanguageDriver
和XMLLanguageDriver
,默认为XMLLanguageDriver
。
- LanguageDriverRegistry中用
LANGUAGE_DRIVER_MAP
来缓存LanguageDriver- key:LanguageDriver的Class
- value:LanguageDriver的实例对象(newInstance())
1.1、XMLLanguageDriver
作用于解析select|update|insert|delete节点为完整的SQL语句,对应XML格式的配置文件,创建SqlSource
和Parameterhandler
- 主要方法1:
createSqlSource(...)
:调用XMLScriptBuilder
创建SqlSource - 主要方法2:
createParameterHandler(...)
: 创建DefaultParameterHandler
//☆☆--XMLLanguageDriver
public class XMLLanguageDriver implements LanguageDriver {
@Override
public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
//NOTE: DefaultParameterHandler
return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
}
@Override
public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {
//NOTE: 通过XMLScriptBuilder构建SqlSource
XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);
return builder.parseScriptNode();
}
@Override
public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
//NOTE: 传入"<script>"脚本的Sql信息,构建SqlSource
if (script.startsWith("<script>")) {
XPathParser parser = new XPathParser(script, false, configuration.getVariables(), new XMLMapperEntityResolver());
return createSqlSource(configuration, parser.evalNode("/script"), parameterType);
} else {
//NOTE: 通过PropertyParser解析"${}"替换成具体的属性值,并直接生成TextSqlNode后构建SqlSource
script = PropertyParser.parse(script, configuration.getVariables());
TextSqlNode textSqlNode = new TextSqlNode(script);
if (textSqlNode.isDynamic()) {
return new DynamicSqlSource(configuration, textSqlNode);
} else {
return new RawSqlSource(configuration, script, parameterType);
}
}
}
}
1.2、RawLanguageDriver
继承自XMLLanguageDrive