java
主页 > 软件编程 > java >

MyBatis中 #{} 和 ${} 的区别介绍

2024-12-09 | 佚名 | 点击:

在MyBatis中,#{}和${}是两种常见的占位符,它们的作用和使用场景有所不同。理解它们的区别对于正确使用MyBatis非常重要。

在Mybatis面试中常涉及到关于#{}和${}的区别

1、#{}是预编译处理,$ {}是字符串替换。

2、MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。

3、使用 #{} 可以有效的防止SQL注入,提高系统安全性。

1. #{} 和 ${} 的基本区别

#{}:SQL参数占位符

作用:#{}用于将传入的参数安全地绑定到SQL语句中,它会自动使用PreparedStatement的?占位符机制,并且MyBatis会对传入的参数进行预处理(例如防止SQL注入)。

参数替换:在生成SQL语句时,#{}会被替换为一个?,然后由JDBC驱动程序将参数值绑定到这个?占位符上。

使用场景:通常用于传递用户输入的参数,如查询条件、插入或更新的数据等。

示例:

1

2

3

<select id="findUserById" resultType="User">

    SELECT * FROM users WHERE id = #{id}

</select>

${}:SQL文本占位符

作用:${}用于直接将传入的参数值替换到SQL语句中,它不会进行预处理,因此直接将参数值插入到SQL语句中。这意味着${}会将参数视为SQL的一部分,可能会导致SQL注入风险。

参数替换:在生成SQL语句时,${}会直接将传入的值替换到SQL语句中,而不会使用?占位符。

使用场景:通常用于动态生成SQL片段,比如排序字段名、表名、列名等不直接来自用户输入的参数。

示例:

1

2

3

<select id="findUserByColumn" resultType="User">

    SELECT * FROM users WHERE ${columnName} = #{value}

</select>

2. 安全性和使用建议

3. 具体示例

使用 #{} 的示例

1

2

3

<select id="findUserById" resultType="User">

    SELECT * FROM users WHERE id = #{id}

</select>

传入id为1,生成SQL为:

1

SELECT * FROM users WHERE id = ?

然后将参数1安全地绑定到?上。

使用 ${} 的示例

1

2

3

<select id="findUserByColumn" resultType="User">

    SELECT * FROM users WHERE ${columnName} = #{value}

</select>

传入columnName为username,value为John,生成SQL为:

1

SELECT * FROM users WHERE username = ?

然后将参数John绑定到?上。

SQL注入风险示例

1

2

3

<select id="findUserByColumn" resultType="User">

    SELECT * FROM users WHERE ${columnName} = #{value}

</select>

如果传入的columnName为username OR '1'='1',生成的SQL可能是:

1

SELECT * FROM users WHERE username OR '1'='1' = ?

这样就可能导致SQL注入问题。

总结

在实际开发中,建议尽量使用#{}来传递参数,以确保SQL安全性,而对于使用${}的场景,需要确保传入的参数是安全且经过验证的。

原文链接:
相关文章
最新更新