SQL中# 与$ 的区别

SQL中# 与$ 的区别

区别:

(1)#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是id,则解析成的sql为order by "id"。

(2)$将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是id,则解析成的sql为order by id。

(3)#方式在很大程度上能够防止sql注入。

(4)$方式无法防止sql注入。

(5)$方式一般用于传入数据库对象,例如传入表名。(这里得注意SQL注入问题

(6)一般能用#的就别用$。

ps:在使用mybatis中还遇到<![CDATA[]]>的用法,在该符号内的语句,将不会被当成字符串来处理,而是直接当成sql语句,比如要执行一个存储过程。

 

总结区别:#{} 传入值时,sql解析时,参数是带引号的,而${}穿入值,sql解析时,参数是不带引号的。

 

举个例子:

select * from ${table_Name} where name = #{name}

在这个例子中,如果表名为

   user; delete user; --

  则动态解析之后 sql 如下:

select * from user; delete user; -- where name = ?;

--之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成致命损伤。

但是表名用参数传递进来的时候,只能使用 ${} 。这也提醒在这种用法中要小心sql注入的问题。

 

防止SQL注入方法:

首先,永远不要相信用户的输入。

(1)不使用SQL,考虑NoSQL。

(2)正则表达式,字符串过滤。

(3)参数绑定PreparedStatement。

(4)使用正则表达式过滤传入的参数。

(5)JSP中调用该函数检查是否包函非法字符或JSP页面判断代码。JSP参考JSP使用过滤器防止SQL注入

<think>好的,我需要回答用户关于SQL#$符号的用法、作用及场景的问题。根据提供的引用内容,用户主要关心的是在MyBatis框架中这两个符号的区别,以及它们如何影响SQL注入和预编译处理。 首先,我应该先明确#{}和${}在MyBatis中的基本区别。根据引用[1]和[3],#{}是预编译处理,能够防止SQL注入,而${}是字符串替换,存在安全风险。需要详细说明两者的工作机制,比如预编译如何处理参数,而字符串替换直接拼接SQL语句,可能导致注入漏洞。 接下来,需要列举它们的使用场景。例如,虽然${}有风险,但在动态表名、字段名或排序时可能需要用到,因为#{}在这些情况下无法正确替换,会导致语法错误。这时候必须使用${},但需要注意手动过滤参数,防止注入攻击。 然后,应该举例说明两者的具体应用,比如在普通参数传递时使用#{},而在动态排序字段时使用${}。同时,引用中提到模糊查询的情况,使用#{}需要结合concat函数,而${}虽然可以但不够安全,这部分也需要解释清楚。 另外,需要提到性能和安全性的权衡。预编译的#{}可以缓存执行计划,提升性能,而${}每次都要重新解析,可能影响性能,但灵活性更高。 最后,总结使用建议,优先使用#{},在必要时谨慎使用${},并采取安全措施。同时生成相关问题,帮助用户进一步理解,比如如何防止SQL注入,动态SQL的应用,或者预编译的其他优点。 需要确保回答结构清晰,分点说明,引用正确的来源,并在适当的位置添加引用标记。同时,检查是否符合系统级指令,如使用中文,正确应用LaTeX格式,生成相关问题等。</think>在SQL(特别是MyBatis框架)中,`#{}`和`${}`符号用于参数替换,但两者在实现方式和安全性上有显著差异。 ### 1. `#{}`的作用及场景 - **作用**: `#{}`是预编译处理,会将参数转换为`?`占位符,并通过JDBC的`PreparedStatement`执行,例如: ```sql SELECT * FROM user WHERE id = #{userId} ``` 实际执行时会变为`SELECT * FROM user WHERE id = ?`,参数值通过安全方式填充[^1][^3]。 - **优势**: - 防止SQL注入攻击,例如输入`&#39; OR 1=1`会被转义为普通字符串而非可执行代码[^2][^3]。 - 支持自动类型转换(如日期、字符串格式化)。 - 预编译语句可重复利用,提升性能。 - **典型场景**: 普通参数传递、模糊查询(需搭配`CONCAT`函数): ```sql SELECT * FROM user WHERE name LIKE CONCAT(&#39;%&#39;, #{keyword}, &#39;%&#39;) ``` --- ### 2. `${}`的作用及场景 - **作用**: `${}`是直接字符串替换,例如: ```sql SELECT * FROM ${tableName} WHERE id = ${userId} ``` 若`tableName`值为`user`,则直接拼接为`SELECT * FROM user WHERE id = 123`。 - **风险**: - 存在SQL注入风险,例如若`tableName`被赋值为`user; DROP TABLE user--`,可能导致数据丢失[^3]。 - 无类型转换,需手动处理格式。 - **适用场景**: 动态表名、字段名、排序语句等无法用预编译占位符的情况: ```sql SELECT * FROM user ORDER BY ${sortField} ASC ``` 使用时需严格校验参数合法性。 --- ### 3. 对比总结 | 特性 | `#{}` | `${}` | |--------------|----------------------------------|--------------------------| | 安全性 | 高(防注入) | 低(需手动过滤风险) | | 执行方式 | 预编译(`PreparedStatement`) | 直接拼接(`Statement`) | | 性能 | 高(可复用执行计划) | 低(每次重新解析SQL) | | 适用场景 | 普通参数、值传递 | 动态表名、字段名、排序 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值