当前位置: 代码网 > it编程>编程语言>Java > MyBatis中$与#的区别解析

MyBatis中$与#的区别解析

2025年07月11日 Java 我要评论
一、介绍#(井号):mybatis使用#{}作为参数占位符时,会创建预处理语句(prepared statement),并将参数值作为预处理语句的参数绑定到sql语句中。使用#可以防止sql注入攻击,

一、介绍

#(井号):mybatis使用#{}作为参数占位符时,会创建预处理语句(prepared statement),并将参数值作为预处理语句的参数绑定到sql语句中。

使用#可以防止sql注入攻击,因为mybatis会自动对参数值进行转义处理。

#{}内部可以是参数的名称或者参数的索引位置(例如#{param1}或者#{1})。

select * from users where username = #{username}

$(美元符号):mybatis使用${}作为参数占位符时,不会创建预处理语句。而是直接将参数值拼接到sql语句中。

使用$不会对参数值进行转义,因此容易受到sql注入攻击,除非参数值是可信的或者已经进行了适当的处理。

${}内部通常是参数的名称。

select * from ${tablename} where id = #{id}

$和#的主要区别:

a、安全性:#提供预处理语句的参数绑定,更安全,可以有效防止sql注入;$直接将参数值拼接到sql语句中,存在sql注入的风险。

b、性能:#通常性能更好,因为预处理语句可以重复使用,而$每次都会生成新的sql语句。

c、使用场景:#适用于大多数情况,特别是当参数是用户输入时;$适用于需要动态指定表名或列名的情况,因为这些部分不能作为预处理语句的参数。

因此,除非有特殊需求,通常推荐使用#来提高sql语句的安全性和性能。

二、sql注入风险实例

1、存在 sql 注入风险的情况(使用 $):

// mapper 接口
public interface usermapper {
    user selectuserbyusername(string username);
}
// xml 映射文件(存在注入风险)
<select id="selectuserbyusername" resulttype="user">
    select * from users where username = '${username}'
</select>

攻击示例:当输入的 username 为 ' or '1'='1 时,最终生成的 sql 语句如下:

select * from users where username = '' or '1'='1'

这个 sql 语句会让所有用户记录都被返回。

2、安全处理方式(使用#)

// mapper 接口
public interface usermapper {
    user selectuserbyusername(string username);
}
// xml 映射文件(安全)
<select id="selectuserbyusername" resulttype="user">
    select * from users where username = #{username}
</select>

3、预编译过程

编译后的 sql:select * from users where username = ?
实际执行时:如果输入的 username 是 ' or '1'='1,jdbc 会对其进行转义,转义后的值为 \' or \'1\'=\'1。
最终效果:查询会去匹配一个名为 ' or '1'='1 的用户,显然这样的用户是不存在的,注入攻击也就失败了。

到此这篇关于mybaits中$与#的区别解析的文章就介绍到这了,更多相关mybaits $与#区别内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com