1. 含义不同

会把传入的数据当成一个占位符,最终在数据上添加一个单引号处理
$ 会把传入的数据直接显示在sql语句中,不会添加单引号

使用 # 的xml文件

  1. <select id="selectUserByYear" resultType="user">
  2. select * from #{year}_user
  3. </select>

image.png
可以看到最终执行的sql 为 select * from ‘2021’_user 这个肯定是有问题的

切换为 $
image.png
数据直接显示在sql语句中

2. 实现方式不同

$作用相等于是字符串拼接
相当于使用StringBuffer的append方法将${year}追加在 _user前

作用相当于变量值替换
相当于使用PreparedStement接口来进行赋值操作。

3. 使用场景

对于sql语句中非变量部分,可以使用$

当 SQL 语句中的元数据(如表名或列名)是动态生成的时候,字符串替换将会非常有用。 举个例子,如果你想 select 一个表任意一列的数据时,不需要这样写:

  1. @Select("select * from user where id = #{id}")
  2. User findById(@Param("id") long id);
  3. @Select("select * from user where name = #{name}")
  4. User findByName(@Param("name") String name);
  5. @Select("select * from user where email = #{email}")
  6. User findByEmail(@Param("email") String email);
  7. // 其它的 "findByXxx" 方法

而是可以只写这样一个方法:

  1. @Select("select * from user where ${column} = #{value}")
  2. User findByColumn(@Param("column") String column, @Param("value") String value);

4. 注意事项

  1. 在sql语句中,如果要接收传递过来的变量的值的话,必须使用#。因为使用#是通过PreparedStement接口来操作,可以防止sql注入,并且在多次执行sql语句时可以提高效率。

  2. $只是简单的字符串拼接而已,所以要特别小心sql注入问题。

  3. 如果在sql语句中能同时使用#和$的时候,最好使用#。