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

395 阅读1分钟

最简单的讲就是:

  • #{} 底层使用PreparedStatement来执行SQL语句
  • ${} 底层使用Statement来执行SQL语句

于是,我们就得到一个结论:

#{} 可以防止SQL依赖注入,而${}是字符串替换(无法防止SQL依赖注入)。所以,我们优先推荐使用#{}

#{}

<mapper namespace="com.xgc.dao.UserDao">
  <select id="findUserById" parameterType="int" resultType="com.xgc.entity.User">
  	select * from user where uid = #{uid};
  </select>
</mapper>

这里 #{} 相当于一个占位符,相当于jdbc中的 ?

假设我们传入的uid为12,那么当该sql被执行的时候,Mybatis底层调用的代码如下:

String sql = "select * from user where uid = ?";
PreparedStatement pstmt = connection.preparedStatement(sql);
pstmt.setInt(1, 12);

${}

<mapper namespace="com.xgc.dao.UserDao">
  <select id="findUserById" parameterType="int" resultType="com.xgc.entity.User">
  	select * from user where uid = ${uid};
  </select>
</mapper>

假设我们传入的uid为12,那么当该sql被执行的时候,Mybatis底层调用的代码如下:

String sql = "select * from user where uid = 12";
Statement stmt = connection.createStatement();
stmt.execute(sql);

JDBC不支持占位符的地方,就只能用 ${} ,典型情况就是 动态参数

比如,我们有两张表,分别是emp_2017、emp_2018。当需要在查询语句中动态指定表名,就只能使用 ${}

<select>
  select * from emp_${year};
</select>

或者是Mybatis排序时动态指定列名,也只能使用 ${}

<select>
  select * from emp order by ${name};
</select>