MyBatis中 #{} 与 ${} 的区别

#{} 在一定程度上防止了SQL注入

使用#{}入参,MyBatis会生成PrepareStatement并且可以安全地设置参数(=?)的值。因为sql语句已经预编译好了,传入参数的时候,不会重新生产sql语句。安全性高。
JDBC中PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

//PreparedStatement预编译
Connection conn = getConn();//获得连接
String sql = "select username, password from user where username=? and password=?"; //执行sql前会预编译号该条语句
PreparedStatement pstmt = conn.prepareStatement(sql); 
pstmt.setString(1,"username"); 
pstmt.setString(2, "password");
ResultSet rs=pstmt.executeUpdate(); 

#将传入的数据都当成一个字符串,会对自动传入的数据加一个引号。

--XML配置SQL语句
SELECT * FROM user WHERE username=#{username}

如果传入的值是 123 ,那么解析成sql时的值为 WHERE username=‘111’,如果传入的值是id,则解析成的sql为WHERE username=‘id’。

${} 如果不对传入参数进行拦截检测,存在很严重的SQL注入问题

将 传 入 的 数 据 直 接 替 换 X M L 中 配 置 的 {} 将传入的数据直接替换XML中配置的 XML{username}等。没有对SQL进行预编译。存在很严重的SQL注入问题。
如:

--XML配置SQL语句
SELECT * FROM user WHERE username=${username} AND password=${password}

如果入参为username=‘AAA’,password=‘aaa’ 在执行时他会将传入的参数username,password替换掉 ${username}。如以下mybatis的日志

### The error may exist in file [E:\JavaWebitems\zxGitee\zxTest-java\target\classes\mybatis-plus\mapping\UserMapping.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT *  FROM user  WHERE username = AAA AND password = aaa
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'AAA' in 'where clause' ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'AAA' in 'where clause'] with root cause

是JDBC中拼接SQL语句的方式

private String getNameByUserId(String username,String password) {
    Connection conn = getConn();//获得连接
   String sql = "select username, password from user where username="+username+" and password="+password;
    PreparedStatement pstmt =  conn.prepareStatement(sql);
    ResultSet rs=pstmt.executeUpdate();
}

这样存在很严重的SQL注入问题,举个简答的例子,传入的参数为 username=‘AAA’–,password=随便写
执行的SQL变为

SELECT * FROM user WHERE username='AAA'-- AND password=随便写

username='AAA’后面的SQL语句被注释掉,不需要密码就可以轻松登录。

结论

在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值