Gorden的博客

停止空谈,开始行动!

mybatis中"#{}"和"${}"的区别

 动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。

  在下面的语句中,如果 username 的值为 zhangsan,则两种方式无任何区别:

select * from user where name = #{name};
select * from user where name = ${name};

  其解析之后的结果均为

select * from user where name = 'zhangsan';

  但是 #{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:

select * from user where name = ?;

  而 ${} 则只是简单的字符串替换,在动态解析阶段,该 sql 语句会被解析成

select * from user where name = 'zhangsan';

  以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

  那么,在使用过程中我们应该使用哪种方式呢?

  答案是,优先使用 #{}。因为 ${} 会导致 sql 注入的问题。看下面的例子:

  

select * from ${tableName} where name = #{name}

  在这个例子中,如果表名为

   user; delete user; -- 

  则动态解析之后 sql 如下:

select * from user; delete user; -- where name = ?;

  --之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。

  但是表名用参数传递进来的时候,只能使用 ${} ,具体原因可以自己做个猜测,去验证。这也提醒我们在这种用法中要小心sql注入的问题。

=================================================

1 #是将传入的值当做字符串的形式,eg:select id,name,age from student where id =#{id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id ='1'.

2 $是将传入的数据直接显示生成sql语句,eg:select id,name,age from student where id =${id},当前端把id值1,传入到后台的时候,就相当于 select id,name,age from student where id = 1.

3 使用#可以很大程度上防止sql注入。(语句的拼接)

4 但是如果使用在order by 中就需要使用 $.

5 在大多数情况下还是经常使用#,但在不同情况下必须使用$.

我觉得#与$的区别最大在于:#{} 传入值时,sql解析时,参数是带引号的,而${}穿入值,sql解析时,参数是不带引号的。

一 : 理解mybatis中 $与#

在mybatis中的$与#都是在sql中动态的传入参数。

eg:select id,name,age from student where name=#{name} 这个name是动态的,可变的。当你传入什么样的值,就会根据你传入的值执行sql语句。

二:使用$与#

#{}: 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个 #{ } 被解析为一个参数占位符 。

${}: 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。

参数: name-->cy

eg: select id,name,age from student where name=#{name} -- name='cy'

select id,name,age from student where name=${name} -- name=cy

在Mybatis的mapper中,参数的传递有2种方式,一种是#{}另一种是${},两者有很大的区别:

#{}实现的是sql语句的预处理参数,之后执行的sql中用?号代替,使用的时候不需要关心数据类型,

mybatis自动实现数据类型的转换,并且可以防止sql注入。

${}实现的是sql语句的直接拼接,不做数据类型的转换,需要自行判断数据类型,不能防止sql的注入。

举个例子:

在分表存储的情况下,我们从那张表查询不确定,也就是说sql语句不能写死了,表明是动态的,

查询条件是固定的:SELECT * FROM $(tableName) where id =#{id}

总结:

#{}占位符,用于参数的传递

${}用于sql语句拼接

#{} 预编译,防止sql注入 不需要关心数据类型, 一个参数时,任意参数名都可以接受参数

${}非预编译 直接字符串的拼接 不可以防止sql注入 需要关系数据类型一个参数时,必须是value


阅读更多
文章标签: ${} #{} MyBatis
个人分类: MyBatis学习总结
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

mybatis中"#{}"和"${}"的区别

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭