#{}是预编译处理,${}是字符串替换。
详情:

(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。

(2)mybatis在处理时 , 就 是 把 {}时,就是把时,就是把{}替换成变量的值。

(3)使用#{}可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。

(4)预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。

首先是使用#{}:

  1. <!-- 使用#{} -->

  2. <select id="selectUser" parameterType="String"

  3. resultType="com.mybatis.po.MyUser">

  4. select * from user where account = #{account} and password = #{password}

  5. </select>

分别测试正常传参和拼接传参:

  1. // 使用#{} 正常传参

  2. Map<String, Object> parameter = new HashMap<>();

  3. parameter.put("account", );

  4. parameter.put("password", password);

  5. MyUser mu = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser", parameter);

  6. System.out.println("返回结果:" + mu);

  7. // 使用#{} 拼接传参

  8. Map<String, Object> parameter_1 = new HashMap<>();

  9. parameter_1.put("account", "201301001");

  10. parameter_1.put("password", "111111" + "or account = 'admin' ");

  11. MyUser mu_1 = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser", parameter_1);

  12. System.out.println("返回结果:" + mu_1);

结果如下:

  1. DEBUG [http-nio-8080-exec-5] - ==> Preparing: select * from user where account = ? and password = ?

  2. DEBUG [http-nio-8080-exec-5] - ==> Parameters: 201301001(String), 111111(String)

  3. DEBUG [http-nio-8080-exec-5] - <== Total: 1

  4. 返回结果:MyUser [id=17, account=201301001, password=111111, name=蒙奇D路飞]

  5. DEBUG [http-nio-8080-exec-5] - ==> Preparing: select * from user where account = ? and password = ?

  6. DEBUG [http-nio-8080-exec-5] - ==> Parameters: 201301001(String), 111111 or account = 'admin' (String)

  7. DEBUG [http-nio-8080-exec-5] - <== Total: 0

  8. 返回结果:null

很明显,使用#{}的时候,即使传入了恶意参数,#{}只会将其作为一个占位符的参数,如上面这个例子:


  1. DEBUG [http-nio-8080-exec-5] - ==> Preparing: select * from user where account = ? and password = ?

  2. DEBUG [http-nio-8080-exec-5] - ==> Parameters: 201301001(String), 111111 or account = 'admin' (String)

  3. DEBUG [http-nio-8080-exec-5] - <== Total: 0

  4. 转换为实际的SQL语句:select * from user where account = '201301001' and password = '111111 or account = 'admin''

现在是使用${}


  1. <!-- 使用${} -->

  2. <select id="selectUser2" parameterType="String"

  3. resultType="com.mybatis.po.MyUser">

  4. select * from user where account = ${account} and password = ${password}

  5. </select>

分别测试正常传参和拼接传参:


  1. // 使用${} 正常传参

  2. Map<String, Object> parameter = new HashMap<>();

  3. parameter.put("account", "201301001");

  4. parameter.put("password", "111111");

  5. MyUser mu = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser2",parameter);

  6. System.out.println("返回结果:" + mu);

  7. // 使用${} 拼接传参

  8. Map<String, Object> parameter2 = new HashMap<>();

  9. parameter2.put("account", "201301001");

  10. parameter2.put("password", "111111" + " or account = 'admin' ");

  11. MyUser mu2 = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser2", parameter2);

  12. System.out.println("返回结果:" + mu2);

结果如下:

  1. DEBUG [http-nio-8080-exec-18] - ==> Preparing: select * from user where account = 201301001 and password = 111111

  2. DEBUG [http-nio-8080-exec-18] - ==> Parameters:

  3. DEBUG [http-nio-8080-exec-18] - <== Total: 1

  4. 返回结果:MyUser [id=17, account=201301001, password=111111, name=蒙奇D路飞]

  5. DEBUG [http-nio-8080-exec-18] - ==> Preparing: select * from user where account = 201301001 and password = 111111 or account = 'admin'

  6. DEBUG [http-nio-8080-exec-18] - ==> Parameters:

  7. DEBUG [http-nio-8080-exec-18] - <== Total: 2

  8. 返回结果:[MyUser [id=1, account=admin, password=111111, name=管理员], MyUser [id=17, account=201301001, password=11

很明显,使用${}将参数拼接后在编译成SQL语句,不能防止SQL注入.如果password的传参是

"11111 or 1=1" 那生成的sql语句是:select * from user where account = 201301001 and password = 111111 or 1=1 ;其作用就相当于 select * from user ,会查出表中所有信息,这是很危险的

【Mybatis中¥{}域#{}的区别】相关推荐

  1. mybatis与php,浅谈mybatis中的#和$的区别

    浅谈mybatis中的#和$的区别 发布于 2016-07-30 11:14:47 | 236 次阅读 | 评论: 0 | 来源: 网友投递 MyBatis 基于Java的持久层框架MyBatis 本 ...

  2. 【mybatis】mybatis中 的# 和 $的区别

    mybatis中 的# 和 $的区别 参考地址:https://www.cnblogs.com/sxdcgaq8080/p/10869144.html 转载于:https://www.cnblogs. ...

  3. MyBatis中selectByExample和selectByExampleWithBLOBs区别

    MyBatis中selectByExample和selectByExampleWithBLOBs区别 先贴一段自动生成的Mapper代码 <select id="selectByExa ...

  4. [转]MyBatis中resultType与resultMap区别

    MyBatis中关于resultType和resultMap的具体区别如下: MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap. res ...

  5. 浅谈 Mybatis中的 ${ } 和 #{ }的区别

    1.美图 一.举例说明 select * from user where name = "dato"; select * from user where name = #{name ...

  6. MyBatis中使用#{}和${}的区别

    1 2 3 select * from table_name where id=#{id}; select * from table_name where id=${id}; 区别: 在动态SQL解析 ...

  7. mybatis中resultMap和resultType区别,三分钟读懂

    先说结论: resultmap与resulttype的区别为:对象不同.描述不同.类型适用不同. 说人话就是,resultmap和resulttype功能差不多,但是resultmap功能更强大 re ...

  8. mybatis中的$与#的区别

    #:占位符 $: 字符拼接符 占位符:占位符就是在某个地方占领一个位置,把它单独作为某个东西,比如这里就是把它作为 值.  字符拼接:字符拼接就是简单的对字符串拼接.没有特殊的其它含义. 当 sele ...

  9. mybatis中$和#号的区别

    #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入. #{}可以接收简单类型值或pojo ...

最新文章

  1. jenkins安装插件一直不动
  2. wxWidgets:wxAutomationObject类用法
  3. 概率图模型中信念传播
  4. java屏蔽关键字_替换禁用语(指定关键字)的过滤器
  5. windows XP上实现python2.7.5和python3.4.3共存
  6. 红宝石服务器文件,使用红宝石MAMP作为本地服务器访问SQL语句
  7. 两数的最大公约数算法基础及优化
  8. 如何使用ListView实现一个带有网络请求,解析,分页,缓存的公共的List页面来大大的提高工作效率
  9. vim 中代码的折叠和打开
  10. 微服务间保持事务一致性
  11. 专硕计算机考研英语一还是二,学硕只会考英语一?专硕只会考英语二?
  12. android读取存储mysql图片,Android从Sqlite数据库保存并获取图像
  13. 39、C++定义一个类,实现向量的加减运算
  14. 模仿某招聘网站的Js搜索菜单
  15. 节税指南|人才引进能节税?速教你掌握精髓!
  16. ArcGIS切片生成工具-ArcGIS缓存管理
  17. 做数据分析需要学什么?这几项技能你掌握了吗?
  18. 产品流程规划的8个阶段
  19. CSS中visibility 属性
  20. 虚拟内存架设服务器客户端,怎么在服务器上开虚拟内存

热门文章

  1. 小甲鱼python课后题百度云盘_【小甲鱼python课后题.doc】下载 - 面包树
  2. 开源的业务中台 全渠道一盘货 订单管理系统 OMS
  3. 【专利写作合集】手把手带着写好专利,拥有大IP
  4. 分享两种给孩子取名字的方法
  5. JavaScript高级程序设计(第4版)(红宝书)的学习笔记
  6. VirtualBox安装出现严重错误
  7. 车厢调度(4种方法)
  8. PlaintextAttack
  9. python中的isdigit()函数
  10. 机械工业出版社 c语言程序设计教程课后题,C语言程序设计