MyBatis中#和$的符号区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yanwenwennihao/article/details/82320887

mybatis中使用Mapper.xml里面的配置进行sql查询,经常需要动态传递参数,例如,我们根据用户的姓名来删选用户是,sql如下:

Select * from user where name=“Jack”;

上述sql中,我们希望name的参数jack是动态可变的,既不同的时刻根据不同的姓名来查询用户,在Mapper.xml文件中使用如下的生气了可以实现动态传递参数 name:

Select * from user where name=#{name};

或者是

Select * from user where name=${name};

 

两者区别

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

 

一个#{}被解析为一个参数占位符?,而${}是一个纯粹的string替换,在动态sql解析阶段将会进行变量替换,总结就是#{} 变量的替换实在DBMS中,${}变量的替换实在动态sql解析阶段

 

用法

1、优先使用#{}

为了性能考虑,相同的预编译sql可以重复利用,其次,${}在预编译之前已经被预编译替换了,这会存在sql注入问题,例如sql:

Select * from ${tableName} where name=#{name};

如果我们的参数tableName 为user,delete user;那么sql动态解析阶段之后,预编译之前的sql将变为:

Select * from user;delete user; --wehre name=?

--之后的语句不起作用,因此本来一台能查询语句偷偷包含了一个删除表的sql语句

 

2、变量作为变量是必须使用${]

因为表名是字符串,使用sql占位符替换字符串时会带上单引号‘ ’,这会导致sql语法错误,例如sql:

Select * from #{tableName} where name=#{name};

于编译之后的sql变为

Select * from ? Where name=?;

假设我们传入的参数为 tableName = "user" , name = "Jack",那么在占位符进行变量替换后,sql 语句变为:

select * from 'user' where name='Jack';  

上述 sql 语句是存在语法错误的,表名不能加单引号 ''(注意,反引号 ``是可以的)。

 

 

四、sql预编译

1. 定义:

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

2. 为什么需要预编译

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

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/yanwenwennihao/article/details/82320887