最简单的讲就是:
#{}底层使用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>