来源:juejin.cn/post/7205192064212123708

推荐:https://t.zsxq.com/bxCb5

前言

在 MyBatis 中,$# 是用来表示 SQL 语句中的参数占位符的两种不同方式,它们有一些重要的区别:

  1. # 的使用

    • # 是 MyBatis 推荐的参数占位符。使用 # 时,MyBatis 会使用预编译的 SQL 语句,并通过 JDBC 的 PreparedStatement 接口设置参数。这种方式可以防止 SQL 注入攻击,因为参数值会被安全地替换。

    • 示例:SELECT * FROM users WHERE id = #{userId}

    • 在上面的例子中,#{userId} 表示一个参数占位符,MyBatis 在执行 SQL 时会将 #{userId} 替换为实际的参数值,并使用 PreparedStatement 进行安全处理。

  2. $ 的使用

    • $ 是直接拼接参数到 SQL 语句中的占位符。使用 $ 时,MyBatis 不会对参数进行预处理,而是直接将参数的值按字面插入 SQL 语句中。

    • 示例:SELECT * FROM users WHERE id = ${userId}

    • 在这个例子中,${userId} 表示一个参数占位符,MyBatis 在执行 SQL 时会将 ${userId} 替换为实际的参数值,直接拼接到 SQL 中,类似于字符串替换。

  3. 区别和适用场景

    • 使用 # 可以防止 SQL 注入攻击,因为参数值会被安全处理。因此,推荐在大多数情况下使用 #
    • 使用 $ 则适合在一些特定的情况下,比如需要动态生成 SQL 语句或者引用 SQL 函数、列名等场景,但需要注意可能带来的安全风险。
  4. 动态 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>

在为数据库表创建索引的示例中,表名,索引名和加索引的列的列名全部都需要使用${}作为参数占位符,否则会报错。在对查询结果集进行排序的示例中,如果列名占位符不使用${}而使用#{},不会报错,但是无法实现根据指定列进行排序的功能。

总结

下面对#{}${}这两种占位符的使用进行一个总结。

  1. #{}占位符会被解析为JDBC中的预编译语句(Prepared Statement)中的参数占位符?,一个#{}会被解析为一个?,而${}占位符标识的位置会直接被替换为入参,是简单的字符串替换;
  2. #{}进行占位符替换后参数会添加上''号,而${}不会;
  3. #{}可以防止SQL注入,以及提高SQL语句执行效率,而${}不具备这些功能;
  4. 当入参为表名和列名时,需要使用${}作为表名和列名的参数占位符。

插播一条消息,帮朋友招聘产品经理、java 开发、算法、测试、AI、安卓逆向工程师,base 一线城市,欢迎大家微信私我简历。3 年到 10 年左右都有,欢迎投递。

本篇文章来源于微信公众号: 业余草



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2024-08-01