目录
Mybatis允许使用 #{} 和 ${} 在编写的SQL语句中进行参数传递,但是二者在使用上存在一些不同,今天就详细解析一下。
一、#{}
#{} 的作用相当于参数绑定,Mybatis会在预编译阶段将 #{} 替换为占位符(比如?),实际的参数值在执行时通过 PreparedStatement
的 set
方法设置,对此,官方文档的描述是:
默认情况下,使用#{}
语法将导致 MyBatis 生成PreparedStatement
属性,并将值安全地设置为PreparedStatement
参数(例如 ?)
- 参数是通过
PreparedStatement
的set
方法设置的,这种方式是安全的,可以防止SQL注入 - 预编译的 SQL 语句可以被重复使用,只需设置不同的参数值即可
- MyBatis 会根据参数值的数据类型自动进行转换,例如将 Java 中的
String
类型转换为数据库中的VARCHAR
类型 - 预编译的 SQL 语句可以提高执行效率,因为编译后的 SQL 语句会被缓存
二、${}
直接将未修改的字符串注入到 SQL 语句中,MyBatis 不会修改或转义字符串。例如,ORDER BY ${columnName}
,当 SQL 语句中的元数据(即表名或列名)是动态的时,字符串替换非常有用。
- 参数是直接拼接到 SQL 语句中的,存在 SQL 注入风险
- 每次拼接不同的参数都会产生一个新的 SQL 语句,每个新语句都需要单独预编译
- 不进行数据类型转换,直接将参数值按字符串拼接到 SQL 语句中,需要保证参数值的类型与 SQL 语句的要求一致
- 由于每次执行 SQL 时都需要拼接字符串,可能不会利用到预编译语句的缓存,影响性能
总结来说,#{}
是安全的参数绑定方式,适用于大多数需要传递参数值的场景,而 ${}
则适用于需要动态构建 SQL 语句的一部分,如表名、列名等,但需要非常小心以避免 SQL 注入风险。在实际开发中,应优先使用 #{}
,并在必要时谨慎使用 ${}