介绍:
源码角度解析:
${}
主要详见TextSqlNode类(org.apache.ibatis.scripting.xmltags.TextSqlNode,文本节点解析类)
// 文本解析入口,可以看到在这里解析了${}标签。GenericTokenParser就比较简单了,查找有没有对应的变量。
// 然后是DynamicContext,这个就是将找到的变量追加到sql上。DynamicContext中使用了一个StringBuilder暂存sql语句
@Override
public boolean apply(DynamicContext context) {
GenericTokenParser parser = createParser(new BindingTokenParser(context, injectionFilter));
context.appendSql(parser.parse(text));
return true;
}
private GenericTokenParser createParser(TokenHandler handler) {
return new GenericTokenParser("${", "}", handler);
}
#{}
详见SqlSourceBuilder类(org.apache.ibatis.builder.SqlSourceBuilder,从RawSqlSource和DynamicSqlSource中调用。将变量替换成?并记录参数信息)
public SqlSource parse(String originalSql, Class<?> parameterType, Map<String, Object> additionalParameters) {
ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);
GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
String sql;
// 解析过程中会记录参数信息,详见当前类内部类ParameterMappingTokenHandler.buildParameterMapping
if (configuration.isShrinkWhitespacesInSql()) {
sql = parser.parse(removeExtraWhitespaces(originalSql));
} else {
sql = parser.parse(originalSql);
}
return new StaticSqlSource(configuration, sql, handler.getParameterMappings());
}
参数设置是在DefaultParameterHandler.setParameters方法中处理的,这个不详细说了,实际上就是调用了PreparedStatement.setXXX