被拷打已老实!面试官问我 #{} 和 ${} 的区别是什么?

news/2024/7/9 5:10:14

引言:在使用 MyBatis 进行数据库操作时,#{}${} 的区别是面试中常见的问题,对理解如何在 MyBatis 中安全有效地处理 SQL 语句至关重要。正确使用这两种占位符不仅影响应用的安全性,还涉及到性能优化。

题目

被拷打已老实!面试官问我 #{} 和 ${} 的区别是什么?

推荐解析

预编译与直接替换

面试官问了我这个问题,直接把我问老实了,求放过,赶忙来写下以下思考:

1)#{}:使用 #{} 时,MyBatis 为 SQL 语句的参数生成一个预编译语句,并通过参数占位符(?)来代替实际的参数值。这种方式是安全的,因为它防止了 SQL 注入攻击,参数值在发送到数据库之前不会被解析为 SQL 的一部分。

如果你有一个查询用户的操作,你可以这样写:

SELECT * FROM users WHERE id = #{userId}

2)${}:相反,使用 ${} 时,参数值被直接替换到 SQL 语句中。这种方式虽然灵活,可以动态替换表名、列名等 SQL 语句的组成部分,但却可能导致 SQL 注入问题,因为参数值如果包含恶意的 SQL 代码也会被执行。

如果你需要动态地选择表名或列名,可以这样使用:

SELECT * FROM ${tableName}

性能考虑

对于性能我得出以下思考:

1)#{} 性能优势:由于使用预编译的 SQL 语句,数据库可以重用相同结构的 SQL 语句,减少编译次数,提高执行效率。

2)${} 性能问题:可能导致每次都要编译新的 SQL 语句,因为 SQL 结构可能因为参数的不同而改变。

类型处理

琢磨琢磨我又发现了新大陆!类型处理~

1)#{} 类型处理:MyBatis 可以根据参数的 Java 类型自动推断数据库类型,处理日期、枚举等复杂类型的转换。

2)${} 类型处理:不进行类型转换,将参数视为纯文本,直接嵌入到 SQL 语句中。

鱼聪明 AI 的回答:

鱼聪明 AI 地址:https://www.yucongming.com/

#{}(参数占位符)

  • 预编译#{} 表达式使得参数在 SQL 语句中以占位符 ? 的形式出现。这意味着 SQL 语句会被预编译并多次执行,参数值在运行时绑定。这种方式对于数据库性能优化至关重要,因为预编译可以减少数据库编译SQL的次数,提高执行效率。
  • 防止 SQL 注入:由于参数不是直接拼接到 SQL 语句中,而是作为一个绑定的值传递给预编译的 SQL 语句,因此 #{} 防止了 SQL 注入的风险。用户输入被当作字符串处理,不会被执行为 SQL 代码的一部分。
  • 类型安全:MyBatis 能够根据 Java 类型自动推断出相应的 SQL 类型。例如,如果你传递一个 Java Date 对象,MyBatis 会适当地处理它与 SQL 日期类型之间的转换。

${}(SQL 字符串拼接)

  • 直接替换:使用 ${} 时,参数值会在解析 SQL 语句之前直接替换到 SQL 字符串中。这意味着你可以通过 ${} 插入动态表名、列名或者其他 SQL 片段,如动态排序条件。
  • 高风险${} 由于是直接将参数内容拼接到 SQL 语句中,所以存在 SQL 注入的风险。如果参数值来自不可控的用户输入,那么可能被注入恶意的 SQL 代码。
  • 灵活性:尽管风险较高,${} 在某些场景下是必要的。特别是在 SQL 语句的某些部分无法通过预编译实现,如动态改变表名或某些数据库函数和命令,${} 提供了必要的灵活性。

推荐文章和书籍

文章:https://zhuanlan.zhihu.com/p/86293659

书籍:《 Java 核心技术卷 I 》

欢迎交流

当讨论 MyBatis 中的 #{}${} 占位符时,我们可以从以下几个角度深入探讨它们的概念、区别和实际应用,以便更好地理解它们在数据库操作中的作用:

1)什么是 #{}${}?它们在 MyBatis 中有什么应用?

2)#{}${} 的工作原理是什么?

3)#{}${} 在实际应用中的选择标准是什么?


http://lihuaxi.xjx100.cn/news/2223013.html

相关文章

集合进阶:List集合

一.List集合的特有方法 1.Collection的方法List都继承了 2.List集合因为有索引,所以多了很多索引操作的方法。 3.add // 1.创建一个集合List<String> list new ArrayList<>(); // 2.添加元素list.add("aaa");list.add("bbb"…

6.S081的Lab学习——Lab7: Multithreading

文章目录 前言一、Uthread: switching between threads (moderate)提示&#xff1a;解析 二、Using threads (moderate)解析&#xff1a; 三、Barrier (moderate)解析&#xff1a; 总结 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招。打算尝试6.S081&#xff0c;将它的…

【论文阅读】-- 时间空间化:用于深度分类器训练的可扩展且可靠的时间旅行可视化

Temporality Spatialization: A Scalable and Faithful Time-Travelling Visualization for Deep Classifier Training 摘要1 引言2 动机3 问题定义4 方法论4.1 时空复合体4.2 复数约简 5 实验6 相关工作7 结论参考文献 摘要 时间旅行可视化回答了深度分类器的预测是如何在训练…

测速小车模块

1.用途&#xff1a;广泛用于电机转速检测&#xff0c;脉冲计数,位置限位等。 2.有遮挡&#xff0c;输出高电平&#xff1b;无遮挡&#xff0c;输出低电平 接线 VCC 接电源正极3.3-5V GND 接电源负极 DO TTL开关信号输出 AO 此模块不起作用 测试原理和单位换算&#xff1a;…

Python数据分析与建模库之从入门到四大库(Numpy、Pandas、Matplotl、Seaborn )教学课程下载

第一阶段课程-Python快速入门&#xff1a; 含&#xff1a;1.系列课程环境配置&#xff1b;2.Python快速入门&#xff1b;3.变量类型&#xff1b;4.LIST基础&#xff1b;5.List索引&#xff1b;6.循环结构&#xff1b;7.判断结构&#xff1b;8.字典&#xff1b;9.文件处理&#…

机器学习课程复习——ANN

Q&#xff1a;ANN&#xff1f; 基本架构 由输入层、隐藏层、输出层等构建前馈/反馈传播 工作原理 先加权求和&#xff1a;每个神经元的输出是输入加权和的激活再送入激活函数&#xff1a;激活函数的存在使得其能够拟合各类非线性任务 联想&#xff1a;像adaboosting的加权求…

Python——Gradio

什么是 Gradio&#xff1f; Gradio 是一个开源的 Python 库&#xff0c;用于创建用户友好的、交互式的网页界面。这个界面可以用来展示和测试机器学习模型&#xff0c;或者任何需要用户输入的 Python 应用程序。Gradio 的目标是让开发者快速地将他们的机器学习模型部署为可供他…

UE5 发射物目标追踪

UE5 发射物目标追踪 思路 求出需要旋转的角度&#xff0c;然后每帧旋转&#xff0c;再更新速度 实现&#xff1a; 求出发射物当前方向和目标方向的旋转后&#xff0c;插值求每帧的旋转。 //向目标旋转 float Speed MovementComponent->Velocity.Length(); //获取发射物…