问题 何时使用$ vs#?


我对使用感到困惑 $ vs #。我没有找到任何指南。我用它们作为
name = #{name}name like '%${word}%'order by name ${orderAs}where name = #{word}
有时,这些工作正常,但有时,参数不包括或给我错误

org.apache.ibatis.reflection.ReflectionException:没有getter   对于名为'name'的财产.......

所以,我想知道何时使用 $ 要么 # ?


11767
2017-10-10 08:34


起源



答案:


以下 myBatis 方针 #{} 在您的sql语句中使用。

如果您查看该部分中的任何MyBatis参考 映射器XML文件 它表示明确:

注意参数表示法:

#{id}

除此以外 ${} 是为了

1-配置 性能

例如:

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

然后可以使用下一个属性:

<dataSource type="POOLED">
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

2-字符串替换 ${} (参数部分):

默认情况下,使用#{}语法将导致MyBatis生成   PreparedStatement属性并安全地设置值   PreparedStatement参数(例如?)。虽然这更安全,更快速   几乎总是首选,有时你只想直接注入一个   字符串未修改为SQL语句。例如,对于ORDER BY,   你可以使用这样的东西:

ORDER BY $ {columnName}

这里MyBatis不会修改或转义字符串。

注意接受用户的输入并将其提供给a是不安全的   声明未经修改的方式。这导致了潜在的SQL   注入攻击,因此您应该禁止用户输入   在这些领域,或总是执行自己的逃生和检查。

如此明确地说 name like '%${word}%' or按名称$ {orderAs}命令,你需要使用字符串替换而不是预备语句。


13
2017-10-10 08:54



name = ${name} , name like '%#{word}%' 这些都不行。 #{}用在你的sql语句中.... 我不明白。我在sql语句中使用mybatis exp。不是吗? $ {}仅适用于Java属性.. 你的意思是这些可能是变形取决于参数类型? - Cataclysm
您可以支持我一个链接,按照您的描述遵循指南吗? - Cataclysm
我编辑了我的答案,对不起,如果不清楚的话 - Pau
感谢您的编辑答案。但我还不满意。你能解释一下为什么吗? order by name #{orderAs} 和 name like '%#{word}%' 给我错误? - Cataclysm
根据本答案中的“2-字符串替换$ {}”这一点的描述的有效部分是“这里MyBatis不会修改或转义字符串”。因此,在#{}不起作用的情况下,我推断它必须是因为“修改”或“转义”,其中$ {}不会这样做。我不确定什么是“修改”的例子,但我认为可能是#{}引用的字符串可能会在它们周围添加引号字符(因为#in this works:“... name IN <foreach item =“item”index =“index”collection =“collection”open =“(”separator =“,”close =“)”>#{item} </ foreach> ...“) - cellepo


答案:


以下 myBatis 方针 #{} 在您的sql语句中使用。

如果您查看该部分中的任何MyBatis参考 映射器XML文件 它表示明确:

注意参数表示法:

#{id}

除此以外 ${} 是为了

1-配置 性能

例如:

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

然后可以使用下一个属性:

<dataSource type="POOLED">
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

2-字符串替换 ${} (参数部分):

默认情况下,使用#{}语法将导致MyBatis生成   PreparedStatement属性并安全地设置值   PreparedStatement参数(例如?)。虽然这更安全,更快速   几乎总是首选,有时你只想直接注入一个   字符串未修改为SQL语句。例如,对于ORDER BY,   你可以使用这样的东西:

ORDER BY $ {columnName}

这里MyBatis不会修改或转义字符串。

注意接受用户的输入并将其提供给a是不安全的   声明未经修改的方式。这导致了潜在的SQL   注入攻击,因此您应该禁止用户输入   在这些领域,或总是执行自己的逃生和检查。

如此明确地说 name like '%${word}%' or按名称$ {orderAs}命令,你需要使用字符串替换而不是预备语句。


13
2017-10-10 08:54



name = ${name} , name like '%#{word}%' 这些都不行。 #{}用在你的sql语句中.... 我不明白。我在sql语句中使用mybatis exp。不是吗? $ {}仅适用于Java属性.. 你的意思是这些可能是变形取决于参数类型? - Cataclysm
您可以支持我一个链接,按照您的描述遵循指南吗? - Cataclysm
我编辑了我的答案,对不起,如果不清楚的话 - Pau
感谢您的编辑答案。但我还不满意。你能解释一下为什么吗? order by name #{orderAs} 和 name like '%#{word}%' 给我错误? - Cataclysm
根据本答案中的“2-字符串替换$ {}”这一点的描述的有效部分是“这里MyBatis不会修改或转义字符串”。因此,在#{}不起作用的情况下,我推断它必须是因为“修改”或“转义”,其中$ {}不会这样做。我不确定什么是“修改”的例子,但我认为可能是#{}引用的字符串可能会在它们周围添加引号字符(因为#in this works:“... name IN <foreach item =“item”index =“index”collection =“collection”open =“(”separator =“,”close =“)”>#{item} </ foreach> ...“) - cellepo