前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《从Java面试题来看源码》,#{} 和 ${} 的区别

《从Java面试题来看源码》,#{} 和 ${} 的区别

作者头像
阿提说说
发布2022-12-02 16:32:26
2120
发布2022-12-02 16:32:26
举报
文章被收录于专栏:Java技术进阶

面试题:#{} 和 ${} 的区别是什么?

#{} 会对 sql 预编译处理,将#{} 替换为占位符,字符串会变为 'xxx'。${} 则是直接替换变量

我们结合项目通过源码来看看两者是怎么解析的。这样不会无聊,也能加深印象。 在 mybatis 与 spring 集成的项目中,SqlSessionFactory 由 SqlSessionFactoryBean 创建

以格式化 delete from sys_attach where id = #{id} 为例时序图是这样,你可以根据根据时序图跟踪源码

格式化后 #{} 会替换成?,表示占位符,预编译语句会使用 PreparedStatement 来处理

如果是 delete from sys_attach where id = ${id},XMLScriptBuilder 前面的过程都是一样的,主要是在 parseScriptNode () 方法中判断是静态 sql, 还是动态 sql, 动态 sql 是返回 DynamicSqlSource 对象,再执行 sql 语句的时候再将 id 赋值

代码语言:javascript
复制
  public SqlSource parseScriptNode() {
   //解析XNode成一系列SqlNode对象,并封装成MixedSqlNode对象,并会判断此SQL是否为动态
    MixedSqlNode rootSqlNode = parseDynamicTags(context);
    SqlSource sqlSource = null;
    if (isDynamic) {
     //是动态Sql
      sqlSource = new DynamicSqlSource(configuration, rootSqlNode);
    } else {
      sqlSource = new RawSqlSource(configuration, rootSqlNode, parameterType);
    }
    return sqlSource;
  }

在运行时会调用DynamicSqlSource.getBoundSql(Object parameterObject)生成SQL语句 

代码语言:javascript
复制
  //在运行时调用
  @Override
  public BoundSql getBoundSql(Object parameterObject) {
      //传入configuration和运行时的参数,创建DynamicContext对象
    DynamicContext context = new DynamicContext(configuration, parameterObject);
    //应用每个SqlNode,拼接Sql片段,这里只替换动态部分
   //此时context的sqlBuilder已经被解析具体的sql语句
    rootSqlNode.apply(context);
    //继续解析SQL,将#{}替换成?
    SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
    Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
    SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
    //创建BoundSql对象
    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
    for (Map.Entry<String, Object> entry : context.getBindings().entrySet()) {
      boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
    }
    return boundSql;
  }

以上就是对该面试题的源码分析。

关注我,给你看更多面试分析 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

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