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

概要

动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。

示例: #{}

假设变量:

String username='smith';

有以下mybatis配置:

select * from user where name = #{username};

#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:

select * from user where name = ?;

类似于如下操作:

PreparedStatement ps = conn.prepareStatement(sql); 
ps.setString(1,username);

DBMS中参数替换,最终SQL语句如下:

select * from user where name = 'smith';

示例: ${}

假设变量:

String username='smith';

有以下mybatis配置:

select * from user where name = ${username};

${} 在动态解析阶段,该 sql 语句会被解析成:

select * from user where name = 'smith';

类似于如下操作:

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);

示例${}的SQL注入

select * from ${tableName} where name = #{userName}

定义变量值如下:

String tableName = "user; delete user; --";
String userName = "smith";

则,解析下,会先查询user表,再无条件删除user表,至于查询条件则被注释起来了

select * from user; delete user; -- where name = 'smith';

示例${}的动态指定排序字段

select * from ${tableName} order by ${sortColumn}

定义变量值如下:

String tableName = "user";
String sortColumn = "createAt desc";

解析SQL如下:

select * from user order by createAt desc

总结

  1. #{}方式能够很大程度防止sql注入。 
  2. ${}方式无法防止Sql注入。
  3. ${}方式一般用于传入数据库对象,例如传入表名,排序字段
  4. 一般能用#{}的就别用${}

声明:转载文章,摘抄自网络各处。

你可能感兴趣的:(Java,Mybatis)