【mybatis】详解 # 和 $ 的区别,两者分别适用于哪种场景,使用 $ 不当会造成什么影响
# 和 $ 的区别
在MyBatis中,# 和 $ 是用来处理参数的两种不同方式,它们之间有一些重要的区别:
# 符号:
# 是用来进行参数占位符的,它会进行 SQL 注入防护。使用 # 时,MyBatis 会将参数值进行预处理,以防止 SQL 注入的问题。
当你在 SQL 语句中使用 #{parameterName} 时,MyBatis 会将 parameterName 所代表的参数值转义,安全地插入 SQL 语句中。
例如:
SELECT * FROM users WHERE username = #{username}
如果 username 是一个用户输入的值,MyBatis 会处理这个值并确保不会引起 SQL 注入。
$ 符号:
$ 用于直接插入参数值,不进行任何处理。这意味着使用 $ 的时候,如果参数包含恶意 SQL 代码,可能会导致 SQL 注入问题。
当你在 SQL 语句中使用 ${parameterName} 时,MyBatis 会直接将 parameterName 的值替换到 SQL 语句中。
例如:
SELECT * FROM ${tableName}
如果 tableName 是用户输入的值,直接插入可能会导致安全风险。
总结:
- **使用
#**:安全,参数经过转义,防止 SQL 注入。适用于 SQL 中的条件值或数据列。 - **使用
$**:不安全,参数不经过处理,直接替换。一般用于列名、表名等需要动态命名的场景,但需谨慎使用。
在实际使用中,建议优先使用 #,只有在确实需要动态 SQL 结构时才考虑使用 $,并确保传入的内容是安全可信的。
#{} 和${} 区别
1. #{}:预编译处理, ${}:字符直接替换
2. #{} 可以防⽌SQL注⼊, ${}存在SQL注⼊的⻛险, 查询语句中, 可以使⽤ #{} ,推荐使⽤ #{}
3. 但是⼀些场景, #{} 不能完成, ⽐如 排序功能, 表名, 字段名作为参数时, 这些情况需要使⽤${}
4. 模糊查询虽然${}可以完成, 但因为存在SQL注⼊的问题,所以通常使⽤mysql内置函数concat来完成
sql注入
下面是一个示例,展示了如何通过使用 $ 符号导致 SQL 注入的情况
假设我们有一个 MyBatis 的 Mapper XML 文件,其中定义了一个可插入表名的 SQL 查询:
<mapper namespace="com.example.UserMapper"><select id="getUsersByTable" resultType="com.example.User">SELECT * FROM ${tableName} WHERE username = #{username}</select>
</mapper>
在这个查询中,${tableName} 采用了 $ 符号,表示我们希望动态插入一个表名,而 #{username} 采用了 # 符号,确保了对用户输入的 username 进行了安全的处理。
SQL 注入示例:
假设调用这个方法的 Java 代码如下:
String userInputTableName = "users; DROP TABLE users; --"; // 用户输入的表名
String username = "exampleUser";List<User> users = userMapper.getUsersByTable(userInputTableName, username);
在上面的代码中,userInputTableName 是来源于不受信任的用户输入。如果用户输入了恶意的 SQL 片段 users; DROP TABLE users; --,那么最终生成的 SQL 会是:
SELECT * FROM users; DROP TABLE users; -- WHERE username = 'exampleUser'
这个查询会导致数据库首先执行 SELECT * FROM users;,然后在同一个执行上下文中执行 DROP TABLE users;,从而将 users 表删除。
解决方案:
为了防止这种 SQL 注入,应该避免在 SQL 语句中使用 ${} 直接插入来自用户的输入。应该采用以下做法:
- 使用预定义表名:使用固定值或通过查证安全的值来避免用户直接输入可能的表名。
- 使用
#符号:对于需要而不应该通过用户直接控制的内容,避免动态 SQL。
例如,我们可以用一个枚举(或其他安全措施)来限制表名:
// 使用合法的表名,防止SQL注入
List<User> users = userMapper.getUsersByTable("users", username);
总之,任何时候都应谨慎对待 SQL 的构建,特别是涉及到用户输入时,确保不使用 $ 来动态插入外部输入内容,以防止 SQL 注入漏洞。
# 与 $ 分别适用的场景
在 MyBatis 中,# 和 $ 各自适用于不同的场景。下面结合代码示例来描述它们的适用场景
使用 # 的场景
# 符号用于安全地绑定参数,适合用于绑定查询条件、列值等情境,确保参数得到转义以避免 SQL 注入。
示例:
<mapper namespace="com.example.UserMapper"><select id="getUserByUsername" resultType="com.example.User">SELECT * FROM users WHERE username = #{username}</select>
</mapper>
使用方式:
String username = "exampleUser";
User user = userMapper.getUserByUsername(username);
在这个示例中,#{username} 会被 MyBatis 安全处理,防止 SQL 注入。这里 # 的使用是非常合适的,因为 username 由用户输入,可能会包含潜在的恶意内容。
使用 $ 的场景
$ 符号用于动态构建 SQL 中的结构,比如表名或列名等,适合参数值是已知的、受控的,不需要转义的场景。使用市在容易导致 SQL 注入时,要十分谨慎,仅在确实安全的情况下才使用。
示例:
<mapper namespace="com.example.UserMapper"><select id="getUsersByTableName" resultType="com.example.User">SELECT * FROM ${tableName} WHERE username = #{username}</select>
</mapper>
使用方式:
String tableName = "users"; // 确保这是一个受控值
String username = "exampleUser";
List<User> users = userMapper.getUsersByTableName(tableName, username);
在这个示例中,${tableName} 用于动态选择表名。在实际使用中,tableName 应该是一个固定的值,确保不会来自于不受信任的用户输入,以避免 SQL 注入。
总结
-
使用
#的场景:- 查询条件、列值等动态内容
- 任何来自用户输入的值
- 需要安全处理以防止 SQL 注入的场景
-
使用
$的场景:- 动态构建 SQL 的结构部分,如表名和列名
- 受控且安全的值,不应直接来自用户输入
在编写 MyBatis SQL 时,务必小心选择使用 # 或 $ 以保护应用程序的安全性。建议优先使用 #,只有在必要且安全的情况下才使用 $。
相关文章:
【mybatis】详解 # 和 $ 的区别,两者分别适用于哪种场景,使用 $ 不当会造成什么影响
# 和 $ 的区别 在MyBatis中,# 和 $ 是用来处理参数的两种不同方式,它们之间有一些重要的区别: # 符号: # 是用来进行参数占位符的,它会进行 SQL 注入防护。使用 # 时,MyBatis 会将参数值进行预处理&…...
Java面试题,数据结构,图的最短路径算法应用于社交网络分析
图的最短路径算法应用于社交网络分析 在一个大型社交网络中,用户想要找到连接两个特定用户的最短路径。假设你已经有了这个社交网络的数据模型,其中节点代表用户,边代表用户之间的关系。请设计一个解决方案,以找出两个用户之间的…...
Tree数据处理
文章目录 一、Tree数据重置二、Tree拆分成二级数据1、过滤数据2、二级数据 Tree组件的数据处理往往需要使用递归,本文归纳一下常见的数据处理情景,持续更新; 一、Tree数据重置 递归的标志就是寻找子元素的集合字段,一般为children…...
idea配置gitee仓库
idea配置gitee 0、fork开源项目 到自己的仓库,这一步相当于创建了一个自己的git仓库,并复制了别人的开源代码。 注意:如果直接下载别人的开源项目,需要从新配置git仓库信息,因为开源项目一般都设置了git信息。而修改…...
SpringBoot 事务
事务是一组操作的集合, 是一个不可分割的操作.会把所有的操作作为一个整体, 一起向数据库提交或者是撤销操作请求. 所以这组操作要么同时成功, 要么同时失败. 为什么需要事务? 我们在进行程序开发时, 也会有事务的需求. 比如转账操作: 第一步:A 账户 -100 元. …...
我的JAVA-Web基础(1)
1.HTML 2.css CSS(层叠样式表)提供了多种选择器来定位HTML文档中的元素,以便可以应用样式。以下是三种常用的选择器简述: ID 选择器: ID选择器使用HTML元素的id属性来定位单个元素。每个页面中id应该是唯一的…...
【Leetcode 热题 100】207. 课程表
问题背景 你这个学期必须选修 n u m C o u r s e s numCourses numCourses 门课程,记为 0 0 0 到 n u m C o u r s e s − 1 numCourses - 1 numCourses−1。 在选修某些课程之前需要一些先修课程。 先修课程按数组 p r e r e q u i s i t e s prerequisites p…...
从CreateDialogIndirectParam起---我与大模型对话
前言: 对当前的大模型来说,一切皆程序,皆标准。只能按照推定的线路行走,就像机器人走进死胡同,不停的踏步也不回头。除非人为去干预它。其实我提出的这个问题前是因为我不清楚了解一部分WinAPI有着严格的检查机制和自毁…...
重温设计模式--建造者模式
文章目录 建造者模式(Builder Pattern)概述建造者模式UML图作用:建造者模式的结构产品(Product):抽象建造者(Builder):具体建造者(Concrete Builderÿ…...
CSS(五):定位
目录 相对定位 绝对定位 固定定位 在 CSS 中,position 属性用于控制元素的定位方式,使我们可以精确地控制元素在页面上的位置。定位分为相对定位、绝对定位、和固定定位 相对定位 相对定位:position: relative; 相对定位意味着元素的位置…...
JSON 系列之2:JSON简单查询
本文为Oracle数据库JSON学习系列的第2篇,讲述如何对存储在数据库中的JSON文档进行简单的查询。 创建测试表,插入2条数据: DROP TABLE colortab PURGE;CREATE TABLE colortab (id NUMBER,color VARCHAR2(4000),CONSTRAINT ensure_json CH…...
SQL 简单查询
目录 一、投影查询 1、指定特定列查询 2、修改返回列名查询 3、计算值查询 二、选择查询 1、使用关系表达式 2、使用逻辑表达式 3、使用 BETWEEN关键字 4、使用 IN关键字 5、使用 LIKE关键字 6、使用 IS NULL/ NOT NULL关键字 7、符合条件查询 三、聚合函数查询 一…...
YOLOv9-0.1部分代码阅读笔记-metrics.py
metrics.py utils\metrics.py 目录 metrics.py 1.所需的库和模块 2.def fitness(x): 3.def smooth(y, f0.05): 4.def ap_per_class(tp, conf, pred_cls, target_cls, plotFalse, save_dir., names(), eps1e-16, prefix""): 5.def compute_ap(recall, prec…...
KaiOS 4.0 | DataCall and setupData implemention
相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…...
nginx-rtmp服务器搭建
音视频服务器搭建 本文采用 nginx/1.18.0和nginx-rtmp-module模块源代码搭建RTMP流媒体服务器 流程 查看当前服务器的nginx版本下载nginx和nginx-rtmp-module源代码重新编译nginx,并进行相关配置(nginx.conf、防火墙等)客户端测试连接测试搭…...
[c++进阶(三)]单例模式及特殊类的设计
1.前言 在实际场景中,总会遇见一些特殊情况,比如设计一个类,只能在堆上开辟空间, 或者是设计一个类只能实例化一个对象。那么我们应该如何编写代码呢?本篇将会详细的介绍 本章重点: 本篇文章着重讲解如何设计一些特殊 的类,包括不能被拷贝,只能在栈/堆上…...
企业内训|高智能数据构建和多模态数据处理、Agent研发及AI测评技术内训-吉林省某汽车厂商
吉林省某汽车厂商为提升员工在AI大模型技术方面的知识和实践能力,举办本次为期8天的综合培训课程。本课程涵盖“高智能数据构建与智驾云多模态数据处理”、“AI Agent的研发”和“大模型测评”三大模块。通过系统梳理从非结构化数据的高效标注与融合,到L…...
009 Qt_显示类控件_QLCDNumber、ProgressBar、Calendar
文章目录 前言LCD NumberProgressBarCalendar Widget 小结 前言 本文将会向你介绍显示类控件中QLCDNumber显示数字、ProgressBar进度条、Calendar日历 LCD Number QLCDNumer 是⼀个专门用来显示数字的控件. 类似于 “老式计算器” 的效果. 属性说明intValueQLCDNumber 显示…...
--spring.profiles.active=prod
rootproduct-qualification:~# ps -ef | grep java root 5110 1 3 16:57 ? 00:00:54 java -jar productQualification.jar --spring.profiles.activeprod root 6476 5797 0 17:26 pts/0 00:00:00 grep --colorauto java好的,你使用 ps …...
深入解析JVM中对象的创建过程
1. 引言 对象是面向对象编程的核心概念之一,它们封装了数据和行为,构成了应用程序的基本构建块。然而,在Java语言中,每当使用new关键字或其他方式创建一个新对象时,背后发生了什么?这个问题的答案隐藏在JV…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
【java面试】微服务篇
【java面试】微服务篇 一、总体框架二、Springcloud(一)Springcloud五大组件(二)服务注册和发现1、Eureka2、Nacos (三)负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
