美文网首页
3. DynamicSqlSource

3. DynamicSqlSource

作者: 元隐 | 来源:发表于2020-01-15 18:29 被阅读0次

先来看一下, 什么是一个BoundSql

public class BoundSql {

  private final String sql;
  private final List<ParameterMapping> parameterMappings;
  private final Object parameterObject;
  private final Map<String, Object> additionalParameters;
  private final MetaObject metaParameters;

如何构造一个boundsql

@Override
  public BoundSql getBoundSql(Object parameterObject) {
    DynamicContext context = new DynamicContext(configuration, parameterObject);
    rootSqlNode.apply(context);
    SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
    Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
    SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
    context.getBindings().forEach(boundSql::setAdditionalParameter);
    return boundSql;
  }

看看 sql里的 #{username} 这种语法是如何解析的

 GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
    String sql = parser.parse(originalSql);

并不神奇, 几个indexOf 就解决了
public String parse(String text) {
    if (text == null || text.isEmpty()) {
      return "";
    }
    // search open token
    int start = text.indexOf(openToken);
    if (start == -1) {
      return text;
    }
    char[] src = text.toCharArray();
    int offset = 0;
    final StringBuilder builder = new StringBuilder();
    StringBuilder expression = null;
    while (start > -1) {
      if (start > 0 && src[start - 1] == '\\') {
        // this open token is escaped. remove the backslash and continue.
        builder.append(src, offset, start - offset - 1).append(openToken);
        offset = start + openToken.length();
      } else {
        // found open token. let's search close token.
        if (expression == null) {
          expression = new StringBuilder();
        } else {
          expression.setLength(0);
        }
        builder.append(src, offset, start - offset);
        offset = start + openToken.length();
        int end = text.indexOf(closeToken, offset);
        while (end > -1) {
          if (end > offset && src[end - 1] == '\\') {
            // this close token is escaped. remove the backslash and continue.
            expression.append(src, offset, end - offset - 1).append(closeToken);
            offset = end + closeToken.length();
            end = text.indexOf(closeToken, offset);
          } else {
            expression.append(src, offset, end - offset);
            break;
          }
        }
        if (end == -1) {
          // close token was not found.
          builder.append(src, start, src.length - start);
          offset = src.length;
        } else {
          builder.append(handler.handleToken(expression.toString()));
          offset = end + closeToken.length();
        }
      }
      start = text.indexOf(openToken, offset);
    }
    if (offset < src.length) {
      builder.append(src, offset, src.length - offset);
    }
    return builder.toString();
  }

当然preparedStatement 的"?" 号在handler.handleToken函数里. 那么${username}这样的语法也就比较好理解了

@Override
    public String handleToken(String content) {
      parameterMappings.add(buildParameterMapping(content));
      return "?";
    }

${username}的handler在这里

public static class VariableTokenHandler implements TokenHandler {
    private Map<String, String> variables = new HashMap<>();

    VariableTokenHandler(Map<String, String> variables) {
      this.variables = variables;
    }

    @Override
    public String handleToken(String content) {
      return variables.get(content);
    }
  }

相关文章

  • 3. DynamicSqlSource

    先来看一下, 什么是一个BoundSql 如何构造一个boundsql 看看 sql里的 #{username} ...

  • 不学无数——组合模式

    组合模式 在DebugMybatis的源码时,在DynamicSqlSource.getBoundSql动态获取s...

  • MyBatis源码阅读【执行】(六)BoundSql获取流程

    一、相关类及接口 SqlSource接口 DynamicSqlSource主要是封装动态SQL标签解析之后的SQL...

  • 3.

    四时田园杂兴 宋 范成大 高田二麦接山青,傍水低田绿未耕...

  • 3.

    明明每天都无聊至极 却每次都是熬到深夜。

  • 3.

    3.宴前谋 眼前的女子一头红发,忽闪忽闪的绿色眼瞳里面防佛若有光,一身与头发相配的简单红色宫服,略施粉黛,看起来甚...

  • 3.

    昨天晚上我给我妈打电话,让她给我买点儿零食吃,我妈下班,正骑电动车走到一半,就接到了我的电话。 我...

  • 3.

    那日,他从B校走出来时,地上的身影已经拉得悠长。一走出校门,正对面恰好是明孝陵园的一个入口。入口处,一块巨大的方形...

  • 3.

    天上的白马在睡觉,水里的秃鹰在奔跑,空中的乌鸦在尖叫,我在大笑.

  • 3.

    林一遇到了

网友评论

      本文标题:3. DynamicSqlSource

      本文链接:https://www.haomeiwen.com/subject/smlaactx.html