来源:juejin.cn/post/7205192064212123708
推荐:https://t.zsxq.com/bxCb5
前言

在 MyBatis 中,$
和 #
是用来表示 SQL 语句中的参数占位符的两种不同方式,它们有一些重要的区别:
-
#
的使用: -
#
是 MyBatis 推荐的参数占位符。使用#
时,MyBatis 会使用预编译的 SQL 语句,并通过 JDBC 的PreparedStatement
接口设置参数。这种方式可以防止 SQL 注入攻击,因为参数值会被安全地替换。 -
示例:
SELECT * FROM users WHERE id = #{userId}
-
在上面的例子中,
#{userId}
表示一个参数占位符,MyBatis 在执行 SQL 时会将#{userId}
替换为实际的参数值,并使用PreparedStatement
进行安全处理。 -
$
的使用: -
$
是直接拼接参数到 SQL 语句中的占位符。使用$
时,MyBatis 不会对参数进行预处理,而是直接将参数的值按字面插入 SQL 语句中。 -
示例:
SELECT * FROM users WHERE id = ${userId}
-
在这个例子中,
${userId}
表示一个参数占位符,MyBatis 在执行 SQL 时会将${userId}
替换为实际的参数值,直接拼接到 SQL 中,类似于字符串替换。 -
区别和适用场景:
-
使用 #
可以防止 SQL 注入攻击,因为参数值会被安全处理。因此,推荐在大多数情况下使用#
。 -
使用 $
则适合在一些特定的情况下,比如需要动态生成 SQL 语句或者引用 SQL 函数、列名等场景,但需要注意可能带来的安全风险。 -
动态 SQL 的处理:
-
在 MyBatis 的动态 SQL 中, #
和$
的行为也有所不同。#
在动态 SQL 中会被替换为?
,而$
则直接替换为参数的字面值。
总之,#
和 $
的选择取决于具体的需求和安全考虑。大多数情况下建议使用 #
,除非确实需要使用 $
的特定功能。
知道了两者的区别后,我们再看看它们这两个占位符与入参之间是如何被替换的。
#{}
占位符会被解析为JDBC中的预编译语句(Prepared Statement)中的参数占位符?
,一个#{}
会被解析为一个?
。
${}
占位符标识的位置会直接被替换为入参,是简单的字符串替换。
本篇文章将结合不同的入参场景对#{}
和${}
进行分析。
入参是基本类型并且参数个数为1
映射接口中查询单条记录的方法定义如下。
<updateid="createIndex">CREATEINDEX${indexName}ON${tableName}<foreachcollection="columnNames"item="columnName"open="("separator=","close=")">${columnName}</foreach></update><selectid="getMyInfosSorted"resultMap="myInfoMap">SELECT*FROMmyinfoORDERBY${columnName}DESC</select>
在为数据库表创建索引的示例中,表名,索引名和加索引的列的列名全部都需要使用${}
作为参数占位符,否则会报错。在对查询结果集进行排序的示例中,如果列名占位符不使用${}
而使用#{}
,不会报错,但是无法实现根据指定列进行排序的功能。
总结
下面对#{}
和${}
这两种占位符的使用进行一个总结。
-
#{}
占位符会被解析为JDBC中的预编译语句(Prepared Statement)中的参数占位符?
,一个#{}
会被解析为一个?
,而${}
占位符标识的位置会直接被替换为入参,是简单的字符串替换; -
#{}
进行占位符替换后参数会添加上''
号,而${}
不会; -
#{}
可以防止SQL注入,以及提高SQL语句执行效率,而${}
不具备这些功能; -
当入参为表名和列名时,需要使用 ${}
作为表名和列名的参数占位符。

插播一条消息,帮朋友招聘产品经理、java 开发、算法、测试、AI、安卓逆向工程师,base 一线城市,欢迎大家微信私我简历。3 年到 10 年左右都有,欢迎投递。
本篇文章来源于微信公众号: 业余草
微信扫描下方的二维码阅读本文
Comments NOTHING