#{}相当于一个预编译中的 ‘?’ 参数占位符,并在Sql解析时将形参值取出,自动加上引号
示例:现有实参为 username = "jojo"
.....
<select id="findUserByName" parameterType="string" resultType="com.demo.domain.User">
select * from user where username = #{username}
</select>
.....
相当于预编译:
select * from user where username = ?
Sql解析为:
select * from user where username = 'jojo'
${}则是完全的参数值替换
示例:现有实参为 username = "jojo"
.....
<select id="findUserByName" parameterType="string" resultType="com.demo.domain.User">
select * from user where username = ${username}
</select>
.....
Sql解析为:
select * from user where username = jojo
Sql注入
使用${}有一个巨大的安全隐患就是有sql注入问题
示例:现有实参为 password = "jojo or 1 = 1"
使用#{}:
.....
<select id="findUserByName" parameterType="string" resultType="com.demo.domain.User">
select * from user where password = #{password}
</select>
.....
Sql解析为:
select * from user where password = 'jojo or 1 = 1' (可以防止sql注入)
使用${}:
.....
<select id="findUserByName" parameterType="string" resultType="com.demo.domain.User">
select * from user where password = ${password}
</select>
.....
Sql解析为:
select * from user where password = jojo or 1 = 1 (sql注入)
使用${}的场景
在参数为表名、字段名的情况下,由于#{}会将参数自动加上引号,会导致sql无法达到预期结果甚至报错,此时只能使用${}
示例: 现有实参 age = "age"
使用#{}:
.....
<select id="findUserByName" parameterType="string" resultType="com.demo.domain.User">
select * from user order by #{age} desc
</select>
.....
Sql解析为:
select * from user order by 'age' desc (此时的'age'相当于一个"值",而非表字段,所以无法得到正确结果)
使用${}:
.....
<select id="findUserByName" parameterType="string" resultType="com.demo.domain.User">
select * from user order by ${age} desc
</select>
.....
Sql解析为:
select * from user order by age desc (得到正确结果)
除了在必须使用${}的情况下使用${},其余情况下推荐使用#{}