先给大家介绍下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注入的问题。

最新文章

  1. postgreSQL的设置自增主键初始值
  2. nginx反向代理tomcat访问时浏览器加载失败,出现 ERR_CONTENT_LENGTH_MISMATCH 问题
  3. POJ - Ubiquitous Religions
  4. 转评:你造promise就是monad吗
  5. 用CSS截断字符串的两种实用方法
  6. 《C#并行编程高级教程》第5章 协调数据结构 笔记
  7. F - Rain on your Parade - hdu 2389(二分图匹配,Hk算法)
  8. 基于visual Studio2013解决C语言竞赛题之1086任务分配
  9. Teacher implements java.io.Serializable
  10. [转载] Jupiter代码审查工具使用参考
  11. 学习笔记 - 用js判断页面是否加载完成实现代码
  12. Java集合详解及List源码分析
  13. SpringBoot2.0之七 实现页面和后台代码的热部署
  14. 性能调优之vmstat命令
  15. BZOJ.1497.[NOI2006]最大获利(最小割 最大权闭合子图Dinic)
  16. vue2.0之Vue Baidu Map 局部注册使用
  17. python venv actieve uninstall pack-name sitepage
  18. 【IT笔试面试题整理】堆栈和队列
  19. 【树】Flatten Binary Tree to Linked List(先序遍历)
  20. Android设置日期DatePickerDialog

热门文章

  1. 我的第一个上线小程序,案例实战篇二——LayaAir游戏开始界面开发
  2. VGGnet——从TFrecords制作到网络训练
  3. NIO - Buffer
  4. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第4节: recycler中获取对象
  5. MUI的踩坑笔记
  6. Hadoop Streaming框架使用(二)
  7. 一个基于NodeJS开发的APP管理CMS系统
  8. C++ 函数 函数的重载 有默认参数的函数
  9. PSP Daily软件beta版本——基于NABCD评论,及改进建议
  10. 王者荣耀交流协会final发布第五次scrum例会