MyBatis中#{}和${}的区别是什么?

tim-qtp...小于 1 分钟MyBatis

#{}是标记一个占位符,可以防止sql注入。 ${}用于在动态sql中拼接字符串,直接将参数值替换到sql语句中,可能导致sql注入。

Mybatisi在处理#时,会将sql中的#替换为?号,调用PreparedStatement的set方法来赋值;

意味着在在sql语句之前进行了预处理,优化好了一个固定的模版,所以后续有危险的参数传入也不会景影响之前的模板逻辑。

那在什么情况下只能使用${}呢?

1. 动态表名或列名

<select id="getDataFromTable" resultType="Map">
    SELECT * FROM ${tableName} WHERE ${columnName} = #{value}
</select>

2. 动态排序(ORDER BY 子句)

<select id="getSortedUsers" resultType="User">
    SELECT id, name, age FROM user ORDER BY ${orderBy}
</select>

3. 动态限制(LIMIT 和 OFFSET 子句)

<select id="getPaginatedUsers" resultType="User">
    SELECT id, name, age FROM user LIMIT ${limit} OFFSET ${offset}
</select>

4. 动态 SQL 片段

如果某些部分需要动态拼接复杂的 SQL 片段,且这些片段不是简单的参数值,使用 ${} 更灵活。

<select id="getUsersByDynamicCondition" resultType="User">
    SELECT id, name, age, gender 
    FROM user 
    WHERE 1=1 
    ${dynamicCondition}
</select>

String dynamicCondition = "AND age > 25 AND gender = 'F'";