前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅析Mybatis的SqlSource 顶

浅析Mybatis的SqlSource 顶

作者头像
算法之名
发布2019-08-20 10:27:00
9100
发布2019-08-20 10:27:00
举报
文章被收录于专栏:算法之名算法之名

在之前的博文中我已经说了SqlSource接口的作用,以及StaticSqlSource,具体参考 Mybatis初始化的builder建造者模式 ,这里主要要说明一下SqlSource接口的另外两个实现类DynamicSqlSource,RowSqlSource.

DynamicSqlSource的接口方法如下

代码语言:javascript
复制
private final SqlNode rootSqlNode; //记录待解析的SqlNode的根节点,在构造函数中引入
代码语言:javascript
复制
@Override
public BoundSql getBoundSql(Object parameterObject) {
  //创建DynamicContext对象,parameterObject为用户传入的实参
  DynamicContext context = new DynamicContext(configuration, parameterObject);
  //从根节点开始,解析根节点下的所有子节点得到的SQL片段追加到context中,最终通过context.getSql()得到完整的SQL语句,这是组合模式最大的好处
  rootSqlNode.apply(context);
  //创建SqlSourceBuilder对象,解析参数属性,将SQL语句中的"#{}"解析成"?"占位符
  SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
  Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
  SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
  //创建BoundSql对象,并将DynamicContext.bindings中参数信息复制到其additionalParameters集合中保存
  BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
  for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {
    boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
  }
  return boundSql;
}

RawSqlSource是SqlSource的另一个实现,逻辑与DynamicSqlSource类似,但是执行时机不同,处理的SQL语句类型也不同,在XMLScriptBuilder.parseDynamicTags()方法中,如果节点只包含"#{}"占位符,不包含动态SQL节点或未解析的"${}"占位符,则不是动态SQL语句,会创建StaticTextSqlNode对象。在XMLScriptBuilder.parseSciptNode()方法中会判断整个SQL节点是否为动态节点,如果不是动态SQL节点,则创建响应的RawSqlSource对象。

代码语言:javascript
复制
public class RawSqlSource implements SqlSource {

  private final SqlSource sqlSource; //StaticSqlSource对象

  public RawSqlSource(Configuration configuration, SqlNode rootSqlNode, Class<?> parameterType) {
    //调用getSql方法,完成SQL语句的拼装和初步解析,与DynamicSqlSource中相同
    this(configuration, getSql(configuration, rootSqlNode), parameterType);
  }

  public RawSqlSource(Configuration configuration, String sql, Class<?> parameterType) {
    //通过SqlSourceBuilder完成占位符的解析和替换操作
    SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
    Class<?> clazz = parameterType == null ? Object.class : parameterType;
    //返回StaticSqlSource
    sqlSource = sqlSourceParser.parse(sql, clazz, new HashMap<String, Object>());
  }

  private static String getSql(Configuration configuration, SqlNode rootSqlNode) {
    DynamicContext context = new DynamicContext(configuration, null);
    rootSqlNode.apply(context);
    return context.getSql();
  }

  @Override
  public BoundSql getBoundSql(Object parameterObject) {
    return sqlSource.getBoundSql(parameterObject);
  }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档