Mybatis的#{}
与${}
格式的占位符区别
当使用#{}
占位符时:
-
SQL语句会进行预编译处理
select * from a_table where id=#{id} 相当于先编译问号前面的语句,当正式执行时,再传入值到问号中执行。 select * from a_table where id=?
预编译:不代入值的情况下,执行编译,后续执行时再将值代入
-
不存在SQL注入的问题
因为使用
#{}
占位符时,SQL语句会进行预编译处理,sql语义已经确定,只是留了一个位置等待参数传进去。最后传进去的值会直接运行。就相当于方法传参。
-
#{}
格式的占位符只能表示某个值,不能表示SQL语句中的某个片段,预编译必须语义正确才能成功,已经预编译后,执行时再将值代入
-
不需要关注参数值的数据类型
使用#{}
占位符时:
<select id="getStandardById" resultMap="StandardResultMap">
SELECT
*
FROM
a_table
WHERE
id=#{id}
</select>
当使用${}
占位符时:
-
会先将值拼接到SQL语句中,再执行编译相关流程
相当于String字符串提前拼接成的sql语句,放到数据库中执行
-
存在SQL注入的风险
就相当于String字符串拼接后再执行,sql语义在拼接时有可能被改变
-
${}
格式的占位符可以表示SQL语句中的任何片段,不仅仅只是某个值而已,只需要保证将值代入后拼接得到的SQL语句是合法的即可SELECT * FROM a_table WHERE ${where} <=传入的参数直接拼接,比如传入where id=1 或者where name='jack' 比较灵活
-
但是,对于非数值类型(字符串、时间等)的值,需要使用一对单引号框住参数值
拼接的sql语句,必须满足sql语法
当使用${}
占位符时:
<select id="testGet" resultMap="StandardResultMap">
SELECT
<include refid="StandardQueryFields"/>
FROM
pms_album
WHERE
${where}
</select>
<!-- List<AlbumStandardVO> testList(
@Param("offset") Integer offset, @Param("count") Integer count); -->
<select id="testList" resultMap="StandardResultMap">
SELECT
<include refid="StandardQueryFields"/>
FROM
pms_album
ORDER BY
id
LIMIT
${offset}, ${count}
</select>