SQL中 # 与 $ 的不同

本文介绍了在SQL中使用#和$的区别,#会自动加引号防止SQL注入,而$直接代入存在注入风险。推荐使用#,在必须使用$时需谨慎处理SQL注入。此外,还提到了PreparedStatement在防止SQL注入中的作用,它通过预编译和参数化查询提供安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

区别:
(1)#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如: #{id},如果传入的值是id,则解析成的sql为"id"。
(2)$将传入的数据直接显示生成在sql中。如:${id},如果传入的值是id,则解析成的sql为id。
(3)#方式在很大程度上能够防止sql注入。
(4)$方式无法防止sql注入。
(5)$方式一般用于传入数据库对象,例如传入表名。(这里得注意SQL注入问题)
(6)一般能用#的就别用$。
ps:在使用mybatis中还遇到<![CDATA[]]>的用法,在该符号内的语句,将不会被当成字符串来处理,而是直接当成sql语句,比如要执行一个存储过程。

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

举个例子:
select * from ${tableName} where XX = #{XX}
在这个例子中,如果表名为
   hsics.abcd --
  则动态解析之后 sql 如下:
select * from hsics.abcd-- where name = ?;
–之后的语句被注释掉。
但是表名用参数传递进来的时候,只能使用 ${} 。这也提醒在这种用法中要小心sql注入的问题。

防止SQL注入方法:
首先,永远不要相信用户的输入。
(1)正则表达式,字符串过滤。
(2)参数绑定PreparedStatement(见下面解释)。
(3)使用正则表达式过滤传入的参数。
(4)JSP中调用该函数检查是否包函非法字符或JSP页面判断代码。JSP参考JSP使用过滤器防止SQL注入
PreparedStatement:
PreparedStatement是用来执行SQL查询语句的API之一,Java提供了 Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程。
PreparedStatement是java.sql包下面的一个接口,用来执行SQL语句查询,通过调用connection.preparedStatement(sql)方法可以获得PreparedStatment对象。数据库系统会对sql语句进行预编译处理(如果JDBC驱动支持的话),预处理语句将被预先编译好,这条预编译的sql查询语句能在将来的查询中重用,这样一来,它比Statement对象生成的查询速度更快。
PreparedStatement如何防止SQL注入式攻击:
恶意注入:
userName = "1' OR '1'='1"; passWord = "1' OR '1'='1";
那么最终SQL语句变成了:SELECT * FROM users WHERE name = '1' OR '1'='1' and pw = '1' OR '1'='1'; 相当于SELECT * FROM users;
可以达到无账号密码亦可登录网站。
使用PreparedStatement的参数化的查询可以阻止大部分的SQL注入。在使用参数化查询的情况下,数据库系统(eg:MySQL)不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。
在组合SQL字符串的时候,先对所传入的参数做字符取代(将单引号字符取代为连续2个单引号字符,因为连续2个单引号字符在SQL数据库中会视为字符中的一个单引号字符,譬如:SELECT * FROM users WHERE name = ' " + userName + " ';
传入字符串userName = " 1' OR 1=1 "把userName做字符替换后变成userName = " 1'' OR 1=1"最后生成的SQL查询语句为:SELECT * FROM users WHERE name = '1'' OR 1=1'
这样数据库就会去系统查找name为" 1 ’ ’ OR 1=1 " 的记录,而避免了SQL注入。
经过试验,确实如此:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
PreparedStatement部分我是看了这篇文章的:
http://www.importnew.com/5006.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值