动态 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注入的问题。

Mabatis中#{}和${}的区别的更多相关文章

  1. MyBatis Mapper.xml文件中 $和#的区别

    MyBatis Mapper.xml文件中 $和#的区别   网上有很多,总之,简略的写一下,作为备忘.例子中假设参数名为 paramName,类型为 VARCHAR . 1.优先使用#{paramN ...

  2. (实用篇)PHP中unset,array_splice删除数组中元素的区别

    php中删除数组元素是非常的简单的,但有时删除数组需要对索引进行一些排序要求我们会使用到相关的函数,这里我们来介绍使用unset,array_splice删除数组中的元素区别吧 如果要在某个数组中删除 ...

  3. javascript中&&和||的区别

    javascript中&&和||的区别 &&和||操作符两边不是布尔类型时,系统会转换成布尔类型值再计算(空字符串.null.0都会被转成false),结果本身不变. ...

  4. mybatis 中#{}与${}的区别 (面试题)

    MyBatis/Ibatis中#和$的区别 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号. 如:order by #user_id#,如果传入的值是111,那么解析成sql时的 ...

  5. OC类方法和实例方法中的self区别

    OC类方法和实例方法中的self Objective-C里面既有实例方法也类方法.类方法(Class Method) 有时被称为工厂方法(Factory Method)或者方便方法(Convenien ...

  6. Activity中与ListActivity中使用listview区别

    Activity中与ListActivity中使用listview区别 一.Activity中与ListActivity中使用listview区别(本身没多大区别,只是ListActivity在lis ...

  7. C字符串和C++中string的区别 &&&&C++中int型与string型互相转换

    在C++中则把字符串封装成了一种数据类型string,可以直接声明变量并进行赋值等字符串操作.以下是C字符串和C++中string的区别:   C字符串 string对象(C++) 所需的头文件名称 ...

  8. javascript中=、==、===区别详解

    javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...

  9. C字符串和C++中string的区别 &&&&C++中int型与string型互相转换

    在C++中则把字符串封装成了一种数据类型string,可以直接声明变量并进行赋值等字符串操作.以下是C字符串和C++中string的区别:   C字符串 string对象(C++) 所需的头文件名称 ...

随机推荐

  1. Linux运维之——每日小技巧,使用awk命令截取每行的指定列数据

    获取/etc/passwd目录下的UID值小于10的数,并输出第一.三列 [root@:vg_adn_tidbCkhsTest:172.31.30.62 ~]#cat /etc/passwd | aw ...

  2. 乘风破浪:LeetCode真题_041_First Missing Positive

    乘风破浪:LeetCode真题_041_First Missing Positive 一.前言 这次的题目之所以说是难,其实还是在于对于某些空间和时间的限制. 二.First Missing Posi ...

  3. 【2017下集美大学软工1412班_助教博客】个人作业2——APP案例分析

    作业要求 个人作业2:APP案例分析 评分结果 按从高到低排列 学号后三位 第二次作业 Total 008 APP案例分析 23 044 第2次作业 19.5 011 App案例分析--XBMC 19 ...

  4. python 使用csv 文件写入 出现多余空行数据解决方案

    因为csv.writerow() 方法会造成读取时每条数据后多一条空数据 解决方案如下: 分为两种情况 python2 和 python3 先说python2版本 with open('xxx.csv ...

  5. leetcode 2. Add Two Numbers [java]

    注意点: 最后的进位 (l1 == null || l1.next == null) break; public ListNode addTwoNumbers(ListNode l1, ListNod ...

  6. Vue2.0中v-for迭代语法变化(key、index)【转】

    转自:http://blog.csdn.net/sinat_35512245/article/details/53966788 Vue2.0的代码中发现 $key这个值并不能渲染成功,问题如下:但是v ...

  7. python第二十八课——编码小常识

    2.内存和硬盘: 内存:计算机硬件组成部分之一,它是一个容器,用来存储数据:处理数据速度快, 存储数据量小:断电死机数据会丢失,短暂性存储数据 硬盘:计算机硬件组成部分之一,它是一个容器,用来存储数据 ...

  8. 方法(method)和函数(function)的区别

    函数是一段代码,通过名字来进行调用.它能将一些数据(参数)传递进去进行处理,然后返回一些数据(返回值),也可以没有返回值. 所有传递给函数的数据都是显式传递的. 方法也是一段代码,通过一个与对象相关联 ...

  9. BZOJ3569:DZY Loves Chinese II(线性基)

    Description 神校XJ之学霸兮,Dzy皇考曰JC. 摄提贞于孟陬兮,惟庚寅Dzy以降. 纷Dzy既有此内美兮,又重之以修能. 遂降临于OI界,欲以神力而凌♂辱众生.   今Dzy有一魞歄图, ...

  10. 使用Tensorflow训练自己的数据

    训练自己的数据集(以bottle为例):   1.准备数据 文件夹结构: models ├── images ├── annotations │ ├── xmls │ └── trainval.txt ...