#{}是预编译处理,${}是字符串替换。
(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。
(2)mybatis在处理${}时,就是把${}直接替换成变量的值,没有转义。
(3)使用#{}可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。
(4)预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。
不过当动态的传入表名,字段名时,需要使用 ${}.
如 select * from ${user} where ${id} = 1;此处使用#{}经过预编译处理后sql语句就会变为
select * from 'user' where 'id' = 1 显然是不可以的.此时就需要使用${},因为其不经过转义,直接替换,在 ordey by时也同样道理.