Java 面试题
目录

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

· 约 3 分钟读完 · 第 203 / 274 章

推荐答案

在 MyBatis 中,#{} 和 ${} 是两种不同的参数占位符,它们的主要区别如下:

  • #{}:用于预编译 SQL 语句,能够有效防止 SQL 注入。MyBatis 会将 #{} 中的内容替换为 ?,并通过 PreparedStatement 进行参数绑定。
  • ${}:用于直接拼接 SQL 语句,不会进行预编译处理。MyBatis 会将 ${} 中的内容直接替换为字符串,可能会导致 SQL 注入风险。

本题详细解读

1. #{} 的使用场景与特点

  • 预编译处理:#{} 会将参数值通过 PreparedStatement 进行预编译处理,生成带有 ? 占位符的 SQL 语句。这种方式可以有效防止 SQL 注入攻击。
  • 参数类型处理:MyBatis 会根据参数的类型自动进行类型转换,例如将字符串类型的参数用单引号包裹。
  • 安全性:由于使用了预编译,#{} 在处理用户输入时更加安全,适合处理动态 SQL 中的参数。

示例:

在这个例子中,#{userId} 会被替换为 ?,并通过 PreparedStatement 进行参数绑定。

2. ${} 的使用场景与特点

  • 直接拼接:${} 会将参数值直接拼接到 SQL 语句中,不会进行预编译处理。这种方式适合用于动态 SQL 中的表名、列名等非参数部分。
  • 无类型处理:${} 不会对参数进行类型转换,直接将参数值作为字符串拼接到 SQL 语句中。
  • 潜在风险:由于直接拼接 SQL,${} 可能会导致 SQL 注入风险,尤其是在处理用户输入时。

示例:

在这个例子中,${tableName} 会被直接替换为表名字符串,而 #{userId} 会被替换为 ? 并进行参数绑定。

3. 使用建议

  • 优先使用 #{}:在大多数情况下,优先使用 #{} 来处理参数,以确保 SQL 语句的安全性和可维护性。
  • 谨慎使用 ${}:只有在需要动态拼接表名、列名等非参数部分时,才使用 ${},并且要确保输入的安全性,避免 SQL 注入风险。

通过理解 #{} 和 ${} 的区别,可以在 MyBatis 中更安全、更高效地编写 SQL 语句。