package org.apache.ibatis.scripting.xmltags;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;
public class DynamicSqlSource implements SqlSource {
private final Configuration configuration;
private final SqlNode rootSqlNode;
public DynamicSqlSource(Configuration configuration, SqlNode rootSqlNode) {
this.configuration = configuration;
this.rootSqlNode = rootSqlNode;
}
@Override
public BoundSql getBoundSql(Object parameterObject) {
DynamicContext context = new DynamicContext(configuration, parameterObject);
1、//先做sql解析
rootSqlNode.apply(context);
SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
2、 //在做参数绑定
SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
context.getBindings().forEach(boundSql::setAdditionalParameter);
return boundSql;
}
}
1、sql解析,具体可以用如下的解析器
其中$在TextSqlNode 进行解析。
2、解析完毕后由后续的SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
进行参数映射
SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
替换参数占位符#{} -> ?. 并且收集参数。
故: ${ } 内部如果有 #{} 变量占位,是可以正常解析的。