Mybatis里的${ }与#{ }的使用区别(观止)


动态 SQL 是 mybatis 的强大特性之一,也是它优于其他 ORM 框架的一个重要原因。mybatis 在对 sql 语句进行预编译之前,会对 sql 进行动态解析,解析为一个 BoundSql 对象,也是在此处对动态 SQL 进行处理的。在动态 SQL 解析阶段, #{ } 和 ${ } 会有不同的表现

1. ${ }与#{ }区别

#{}:占位符号(参数标记符),将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。优点:预编译,防止sql注入,安全。变量的替换是在 DBMS 中。Mybatis会把这个参数转换成一个字符串。

 

${}sql拼接符号,将传入的数据直接显示生成在sql中。有sql注入风险。变量的替换阶段是在动态 SQL 解析阶段。Mybatis不会对$传递的参数做任何处理,${}会直接参与sql编译,会影响sql语句的预编译。

 

2. ${ }与#{ }使用范围不同(以MySQL为例)

一般能用#的就别用$$符是直接拼成sql的 ,#符则会以字符串的形式 与sql进行拼接。Mybatis在处理#时,会调用PreparedStatement的set系列方法来赋值;处理$时,就是把${para}替换成变量的值。

 

${ }:一般用于传入数据库对象,例如传入表名,如:$(表名);一般用于order by的后面,如:order by $(字段);表名作为变量时,必须使用 ${ };用在我们能够确定值的地方,也就是我们程序员自己赋值的地方;

#{ }:多用于传递查询的参数;一般用在用户输入值的地方,在sql中:字段 比较符号(=、>、<、!=、<>) #{用户输入的值}

 

所以,给个结论吧:一般看到sql的xml配置文件里有:表的某个字段比较符号(=、>、<、!=、<>) #{变量}  这样形式的一定都要用#{} ;order by后面跟字段、表名 这样的情况一定要用${ } 。



3.sql预编译

定义

sql预编译是指 数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。

优点

JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优化 sql 的执行。预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。预编译语句对象可以重复利用。把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。mybatis 默认情况下,将对所有的 sql 进行预编译。

 

4.注意

在使用mybatis中还遇到<![CDATA[]]>的用法,在该符号内的语句,将不会被当成字符串来处理,而是直接当成sql语句,比如要执行一个存储过程。

 

猜你喜欢

转载自blog.csdn.net/superit401/article/details/80186854