先给大家介绍下MyBatis中#{}和${}的区别,具体介绍如下:

1. $将传入的数据直接显示生成在sql中

2. #方式能够很大程度防止sql注入。 

3.$方式无法防止Sql注入。

4.$方式一般用于传入数据库对象,例如传入表名.

5.一般能用#的就别用$.

MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。如果使用#Mybatis排序不起作用,会使用默认asc

order by #{columnName} desc 不会起作用,会使用默认的asc

order by ${columnName} desc 会起作用

字符串替换

默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}

这里MyBatis不会修改或转义字符串。

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

mybatis本身的说明:

String Substitution
By default, using the #{} syntax will cause MyBatis to generate PreparedStatement properties and set the values safely against the PreparedStatement parameters (e.g. ?). While this is safer, faster and almost always preferred, sometimes you just want to directly inject a string unmodified into the SQL Statement. For example, for ORDER BY, you might use something like this:
ORDER BY ${columnName}
Here MyBatis won't modify or escape the string.
NOTE It's not safe to accept input from a user and supply it to a statement unmodified in this way. This leads to potential SQL Injection attacks and therefore you should either disallow user input in these fields, or always perform your own escapes and checks.

从上文可以看出:

1. 使用#{}格式的语法在mybatis中使用Preparement语句来安全的设置值,执行sql类似下面的:

  PreparedStatement ps = conn.prepareStatement(sql);
  ps.setInt(1,id);
   这样做的好处是:更安全,更迅速,通常也是首选做法。

2. 不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:

 ORDER BY ${columnName}

此时MyBatis 不会修改或转义字符串。

这种方式类似于:

 Statement st = conn.createStatement();
 ResultSet rs = st.executeQuery(sql);

  这种方式的缺点是:

以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。

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

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

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

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

   user; delete user; --

  则动态解析之后 sql 如下:

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

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

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

Mybatis笔记八:MyBatis中#{}和${}的区别的更多相关文章

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

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

  2. Mybatis的mapper文件中$和#的区别

    一般来说,我们使用mybatis generator来生成mapper.xml文件时,会生成一些增删改查的文件,这些文件中需要传入一些参数,传参数的时候,我们会注意到,参数的大括号外面,有两种符号,一 ...

  3. 【mybatis笔记】 resultType与resultMap的区别

    序言: 昨天做一个项目,看到很多刚开始用mybatis的同事对于resultType和resultMap的理解与使用含糊不清,这里我试图用最好理解的说法写一写,欢迎大家勘误. 两者异同: 相同点:re ...

  4. Mybatis学习笔记(八) —— Mybatis整合spring

    一.整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代 ...

  5. Mybatis笔记 – insert语句中主键的返回

    在DBMS中可以使用insert语句显示指定自增主键值,但Mybatis中不可,即使指定了也无效,可以使用特殊的方式返回主键. 一.自增主键返回         mysql自增主键执行insert提交 ...

  6. Mybatis的mapper文件中#和$的区别 以及 resultType和resultMap的区别

    一般#{}用于传递查询的参数,一般用于从dao层传递一个string或者其他的参数过来,mybatis对这个参数会进行加引号的操作,将参数转变为一个字符串. SELECT * FROM employe ...

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

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

  8. MyBatis中#{ }和${ }的区别,数据库优化遵循层次和查询方法

    MyBatis中#{ }和${ }的区别详解 1.#将传入的数据当成一个字符串,会对自动传入的数据加一个 双引号. 例如order by #id#,如果传入的值是111,那么解析成sql时变为orde ...

  9. mybatis中的#{}和${}区别

    mybatis中的#{}和${}区别 2017年05月19日 13:59:24 阅读数:16165 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #use ...

随机推荐

  1. Spring Data REST PATCH请求远程代码执行漏洞(CVE-2017-8046) 本地复现方法

      #1背景 Spring Data REST是Spring Data项目的一部分,可以轻松地在Spring Data存储库之上构建超媒体驱动的REST Web服务. 恶意的PATCH请求使用精心构造 ...

  2. telnet命令详解

    基础命令学习目录 原文链接:https://www.cnblogs.com/PatrickLiu/p/8556762.html telnet命令用于登录远程主机,对远程主机进行管理.telnet因为采 ...

  3. 自制session

    原理 1.面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ .__delitem__.__setitem__方法 2.Tornado框架中,默认执行Handler的get/pos ...

  4. python将response中的cookies加入到header

    url = “http://abad.com”header = { "user-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64 ...

  5. React Native 之 main.jsbundle生成方法

    通过react-native init yooweiProject 生成的RN项目(版本基于0.57),目录结构如下 项目结构: 大家可以发现main.jsbundle 是红色的,不存在的,这个属于正 ...

  6. 解决SecureCRT小键盘乱码

    SecureCRT软件菜单,Options -> Session Options ->Terminal -> Emulation,右侧面板中"Terminal"选 ...

  7. iOS开发学习-资源打包

    图片是被放到Images.xcassets中 1.部署版本在>=iOS8的时候,打包的资源包中的图片会被放到Assets.car 图片被压缩: 2.部署版本在<iOS8的时候,打包的资源包 ...

  8. Java 面试-- 1

    JAVA面试精选[Java基础第一部分]   这个系列面试题主要目的是帮助你拿轻松到offer,同时还能开个好价钱.只要能够搞明白这个系列的绝大多数题目,在面试过程中,你就能轻轻松松的把面试官给忽悠了 ...

  9. 软工1816 · Beta冲刺(4/7)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 推进安卓端各个接口的开发,安卓端各个接口已经基本完成 完成食堂各个平面图的绘制 ...

  10. C++自学随笔

    主要学习内容: 了解了IDE环境的含义 C++与C的区别: 新的数据类型:bool型 新的初始化方法:直接初始化int x(1024) 经过查找,了解了直接初始化与复制初始化的区别:"当用于 ...