mybatis中#和$的区别

前言

在原生的操作数据库的代码中,常常会用到PreparedStatement和Statement两个对象,其中PreparedStatement继承自Statement,这两个对象之间的区别之一就是PreparedStatement会对sql进行预编译处理,而Statement不会。有如下代码示例:

// 使用PreparedStatement对象
//定义sql语句,变量的位置用?号代替
String sql = "select user_id, user_name, user_age from user_info where user_id = ?";
//通过Connection得到预编译后的对象,相对于Statement这一步消耗很大,不过优势体现在后面,因为sql已经预编译过了
PreparedStatement ps = conn.preparedStatement(sql);
//给PreparedStatement对象设值,sql中有几个?号就要设几个值,下标从1开始
ps.setInt(1, user.getUserId());
//ResultSet接收查询得到的结果集
ResultSet rs = ps.executeQuery();

//使用Statement对象
//定义sql语句,采用字符串拼接的方式
String sql = "select user_id, user_name, user_age from user_info where user_id = " + user.getUserId();
//通过Connection获取Statement对象
Statement stmt = conn.createStatement();
//ResultSet接收结果集
ResultSet rs = stmt.executeQuery();

在以上的代码中可以看到,PreparedStatement执行sql时会先将sql预编译,这时如果恶意插入一段sql语句(即SQL注入)也不会成功执行,但是在Statement中,sql是通过字符串拼接获取,所以如果插入的sql符合一定条件是会执行的,从而达到恶意攻击的目的。

区别

1、#{}是预编译处理,Mybatis在处理sql语句时,会将sql中的#{}符号替换成?,然后使用PreparedStatement的set方法来赋值,并且传入值后,会在值的两边加上单引号

2、${}是字符串替换,mybatis在处理sql语句时,会将sql中的${}符号直接替换成变量的值,同时,替换的值的两边不会加上单引号,所以可能会导致sql注入

 

原文地址:https://www.cnblogs.com/zhangcaihua/p/13936091.html