从源码的角度看Java中动态sql技术细节,来阐述#{name}和${name}的区别?

本文详述了Java中动态SQL技术的关键细节,特别是Mybatis中#{name}和${name}的区别。#{name}作为参数占位符,用于PreparedStatement的setObject()方法,而${name}则在解析XML时静态替换,涉及OGNL表达式和Properties文件的属性。文章还探讨了TokenHandler、DynamicSqlSource的生成原理及BoundSql的使用。
摘要由CSDN通过智能技术生成

本篇文章重点阐述一些动态sql的技术细节,#{name}和${name}的区别,将在本篇文章中揭晓。也许读者早已了解它们之间的区别,但是,作为技术内幕,我们不仅要了解它们的区别,还要介绍它们的工作原理。

我在这里分享一个,有很多干货,包含jvm,netty,spring,线程,spring cloud等详细讲解,也有详细的学习规划图,面试题整理等,我感觉在面试这块讲的非常清楚:获取面试资料只需:点击这里领取!!! 暗号:CSDN在这里插入图片描述

1. #{name}和${name}的区别。

#{name}:表示这是一个参数(ParameterMapping)占位符,值来自于运行时传递给sql的参数,也就是XXXMapper.xml里的parameterType。其值通过PreparedStatement的setObject()等方法赋值。

动态sql中的标签绑定的值,也是使用#{name}来使用的。

#{name}用在sql文本中。

n a m e : 表 示 这 是 一 个 属 性 配 置 占 位 符 , 值 来 自 于 属 性 配 置 文 件 , 比 如 j d b c . p r o p e r t i e s , 其 值 通 过 类 似 r e p l a c e 方 法 进 行 静 态 替 换 。 比 如 {name}:表示这是一个属性配置占位符,值来自于属性配置文件,比如jdbc.properties,其值通过类似replace方法进行静态替换。比如 namejdbc.propertiesreplace{driver},将被静态替换为com.mysql.jdbc.Driver。

${name}则可以用在xml的Attribute属性,还可以用在sql文本当中。

<select id="countAll" resultType="${driver}">
    select count(1) from (
      select 
      stud_id as studId
      , name, email
      , dob
      , phone
    from students #{
   offset}, ${
   driver}
) tmp 
  </select>

2. ${name}的工作原理

org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode()部分源码。

 public void parseStatementNode() {
   
//...
    XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
    includeParser.applyIncludes(context.getNode());
// ...
}

org.apache.ibatis.builder.xml.XMLIncludeTransformer.applyIncludes(Node, Properties)部分源码。
private void applyIncludes(Node source, final Properties variablesContext) {
   
    if (source.getNodeName().equals("include")) {
   
      // new full context for included SQL - contains inherited context and new variables from current include node
      Properties fullContext;

      String refid = getStringAttribute(source, "refid");
      // replace variables in include refid value
      refid = PropertyParser.parse(refid, variablesContext);
      Node toInclude = findSqlFragment(refid);
      Properties newVariablesContext = getVariablesContext(source, variablesContext);
      if (!newVariablesContext.isEmpty()) {
   
        // merge contexts
        fullContext = new Properties();
        fullCon
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值