MyBatis中的#{}与${}的区别和应用详解

news/2025/2/7 9:53:55/

MyBatis中的#{}与${}的区别和应用详解

在使用MyBatis进行数据库操作时,经常会用到动态SQL语句。为了动态地拼接SQL,MyBatis提供了两种占位符方式:#{} 和 ${}。这两者有着不同的用法和特性,在实际开发中需要根据具体的场景选择使用哪一种。在这篇博客中,我们将详细解析#{}和${}的区别和应用,并结合实际例子加深理解。

一、#{}与${}的基础介绍

1.1 #{}的使用

#{}是MyBatis中的占位符语法,表示参数值会被替换成SQL语句中的参数,同时它会将传入的参数进行预编译。MyBatis会自动为参数值做类型转换,并且防止SQL注入。具体来说,`#{}会通过PreparedStatement绑定参数,在SQL执行前对参数进行处理和转义,从而避免了SQL注入的问题。

示例:使用#{}进行参数传递
java"><select id="getUserByName" parameterType="String" resultType="User">SELECT * FROM users WHERE username = #{username}
</select>

假设传入的username参数为zhangxiangwei,最终执行的SQL为:

SELECT * FROM users WHERE username = 'zhangxiangwei'

注意,`#{}会自动为字符串参数加上单引号,从而防止SQL注入。

1.2 ${}的使用

${}是MyBatis中的另一种占位符语法,它不会对参数进行预编译,而是直接将参数值拼接到SQL语句中。由于没有预编译,${}存在SQL注入的风险,因此使用时必须谨慎。

示例:使用${}进行参数传递
java"><select id="getUserByField" parameterType="String" resultType="User">SELECT ${fieldName} FROM users WHERE user_age = 22
</select>

如果传入的fieldName参数为user_name,那么最终执行的SQL为:

SELECT user_name FROM users WHERE user_age = 22

这里,user_name直接拼接到SQL语句中,而没有加上单引号,且没有进行任何类型转换。

二、#{}与${}的区别

2.1 安全性

  • #{}:使用#{}时,MyBatis会对传入的参数进行预编译,并自动转义参数内容,这样可以有效防止SQL注入攻击。
  • ${}:使用${}时,传入的参数会直接拼接到SQL中,无法进行参数值的转义或预编译,这就导致了SQL注入的风险。必须特别注意,如果使用${},你需要确保传入的参数是可信的。

2.2 适用场景

  • #{}:适用于传入具体的字段值、常规的查询条件等。大多数情况,尤其是涉及用户输入时,推荐使用#{}
  • ${}:通常用于动态拼接字段名、表名等不可预见的内容。当字段或表名需要动态变化时,使用${}可以实现动态拼接。

2.3 性能

  • #{}:使用`#{}时,MyBatis会生成预编译的SQL语句,能够提高性能,因为数据库可以缓存预编译语句并避免每次都解析SQL。
  • ${}:每次使用${}时,MyBatis都会生成新的SQL语句并直接发送给数据库执行,这可能会影响性能,尤其是在高并发环境下。

2.4 SQL注入风险

  • #{}:由于采用了预编译,#{}能够有效防止SQL注入。
  • ${}:由于直接拼接参数值,${}极易引发SQL注入攻击。如果不加防范措施,恶意用户可以通过构造特殊输入来修改SQL语句,进行非法操作。

三、实际应用中的选择

3.1 使用#{}防止SQL注入

场景:当需要传递查询条件值、ID、字符串等数据时,应优先使用`#{},如查询用户时传入用户名。

java"><select id="getUserByName" parameterType="String" resultType="User">SELECT * FROM users WHERE username = #{username}
</select>

优点

  • 自动防止SQL注入
  • 支持类型转换和参数转义

3.2 使用${}进行动态SQL拼接

场景:当需要动态指定表名或字段名时,可以使用${}。例如,生成动态排序SQL时。

java"><select id="getUsersWithDynamicSorting" parameterType="map" resultType="User">SELECT * FROM usersWHERE 1=1  <!-- 为了方便拼接,可以始终使用一个始终成立的条件 --><if test="sortField != null and sortOrder != null">ORDER BY ${sortField} ${sortOrder}</if>
</select>

这里,sortFieldsortOrder是动态传入的值。使用${}来直接拼接排序字段和排序顺序,避免了#{}无法用于列名和排序字段的局限。

注意:在使用${}时,务必确保传入的字段或表名是可信的。如果sortField来自用户输入,可能会引发SQL注入风险。

3.3 使用#{}实现模糊查询

当使用#{}进行模糊查询时,可以结合LIKE语句来实现,避免SQL注入。

java"><select id="searchUser" parameterType="String" resultType="User">SELECT * FROM users WHERE username LIKE CONCAT('%', #{username}, '%')
</select>

在这个例子中,#{}会安全地传递username参数,并将其包含在LIKE查询条件中。

四、总结

  1. #{} 是MyBatis中最常用的占位符,适用于大多数情况,能够防止SQL注入并提高SQL性能。
  2. ${} 适用于动态拼接表名、字段名等结构性内容,但要小心SQL注入风险。
  3. 在实际开发中,尽量使用#{},只在无法使用#{}的情况下(如动态列名、表名等)使用${}
  4. 动态SQL时,尤其是涉及排序等操作时,使用${}来拼接字段名和排序方式。

通过掌握#{}和${}的使用方式,可以在保证代码安全性的同时,灵活地进行动态SQL的拼接和查询。


http://www.ppmy.cn/news/1570042.html

相关文章

Unity 2D实战小游戏开发跳跳鸟 - 跳跳鸟碰撞障碍物逻辑

在有了之前创建的可移动障碍物之后,就可以开始进行跳跳鸟碰撞到障碍物后死亡的逻辑,死亡后会产生一个对应的效果。 跳跳鸟碰撞逻辑 创建Obstacle Tag 首先跳跳鸟在碰撞到障碍物时,我们需要判定碰撞到的是障碍物,可以给障碍物的Prefab预制体添加一个Tag为Obstacle,添加步…

C语言的物联网

C语言在物联网中的应用 物联网&#xff08;Internet of Things&#xff0c;IoT&#xff09;是一个通过网络将各种物理设备连接起来的系统&#xff0c;使其能够收集和交换数据。随着技术的进步&#xff0c;物联网已经走入了我们的日常生活&#xff0c;并在智能家居、智能城市、…

Android-retrofit源码解析

目录 一&#xff0c;前言 二&#xff0c;使用 三&#xff0c;源码分析 一&#xff0c;前言 retrofit是目前比较流行的网络框架&#xff0c;但它本身并没有网络请求的功能&#xff0c;网络请求的功能是由okhttp来完成的。retrofit只是负责网络请求接口的封装&#xff0c;让我们…

selenium记录Spiderbuf例题C01

防止自己遗忘&#xff0c;故作此为记录。 步骤&#xff1a; &#xff08;1&#xff09;进入例题&#xff0c;找到需要点击的元素。 可得button xpath&#xff1a; click_xpath: str r//li/a[title"mnist"] WebDriverWait(driver, 10).until(expected_conditions.…

将音频mp3文件添加背景音乐

你可以使用 Python 的 pydub 库来合成两个音频文件&#xff0c;并调整背景音乐的音量&#xff0c;使朗诵的声音更强。以下是实现的 Python 代码&#xff1a; 步骤 读取朗诵音频文件&#xff08;speech.mp3&#xff09;。读取背景音乐文件&#xff08;background.mp3&#xff…

项目顺利交付,几个关键阶段

年前离放假还有10天的时候&#xff0c;来了一个应急项目&#xff0c; 需要在放假前一天完成一个演示版本的项目&#xff0c;过年期间给甲方领导看。 本想的最后几天摸摸鱼&#xff0c;这么一来&#xff0c;非但摸鱼不了&#xff0c;还得加班。 还在虽然累&#xff0c;但也是…

LiteDB 使用教程

一、引言 在软件开发中&#xff0c;数据存储和管理是至关重要的一环。对于小型项目或者对性能和便捷性有较高要求的场景&#xff0c;传统的大型数据库可能显得过于笨重。而 LiteDB 作为一款轻量级的嵌入式 NoSQL 数据库&#xff0c;为开发者提供了一个简洁、高效的解决方案。它…

深度学习|表示学习|卷积神经网络|NIN 相比普通 CNN|17

如是我闻&#xff1a; Network in Network (NIN) 是 2014 年由 Min Lin 等人 提出的一个改进 CNN 结构的模型。它的核心思想是&#xff1a;用小型的多层感知机&#xff08;MLP&#xff0c;Multi-Layer Perceptron&#xff09;替代传统 CNN 中的卷积层&#xff0c;从而提高网络的…