myBatis中的#和$的区别

  MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。  

  动态sql 是 mybatis 的主要特性之一,在mybatis中我们可以把参数传到xml文件,由mybatis对sql及其语法进行解析,mybatis支持使用${}和#{}。可能有些人没有留意到,认为${}和#{}的作用一样,其实他们的功能相似,但还是有区别的。

对比

1、使用${}方式传入的参数,mybatis不会对它进行特殊处理,而使用#{}传进来的参数,mybatis会对其进行转义。可能在赋值给如id=#{id}和id=${id}看不出多大区别,但是作为表名或字段参数时可以明显看出,可以看看下面的例子:

假设传入的参数为表名test

selec * from #{table};  解析后是: select * from "test"; 而

select * from ${table}; 解析后是:select * from test;

很明显,前者多了字符串的引号,会失败,后者正常查询会成功;

所以对于传入分组(Group)字段或者排序字段(order by),应使用${},避免出现order  by "id" 等情况

2、#和$在预编译处理中是不一样的。#类似jdbc中的PreparedStatement,对于传入的参数,在预处理阶段会使用?代替,比如:

select * from student where id = ?;

待真正查询的时候即在数据库管理系统中(DBMS)才会代入参数。

而${}则是简单的替换,如下:

select * from student where id = 2;

$只是占位,传什么就替换成什么,直接显示出来,#代表的就是参数,会进行转义,所以一般都是使用#,$不安全

总结 

1、能使用#{}的地方应尽量使用#{}

2、像PreparedStatement ,#{}可以有效防止sql注入,${}则可能导致sql注入

所谓sql注入,就是指把用户输入的数据拼接到sql语句后面作为sql语句的一部分执行,例如:

select * from user where name=' "+name+" ' and password=' "+password+" '

那么只要用户输入用户名admin和密码123456' or  'abc' = 'abc',那么拼接出来的语句就为

select * from user where name=' admin ' and password='123456' or 'abc'= 'abc';

这样只要user表有数据,就会返回结果,达到sql注入的目的。同样,用户输入用户名a'则 and password=' "+password+" '就会被注释掉,也达到注入sql的目的。

3. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
4. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,  如果传入的值是id,则解析成的sql为order by id.
5.$方式一般用于传入数据库对象,例如传入表名.

这里顺带提下防止sql注入的几种方式(可能不止这几种):

(1)、jdbc使用 PreparedStatement代替Statement,PreparedStatement 不仅提高了代码的可读性和可维护性.而且也提高了安全性,有效防止sql注入;

(2)、在程序代码中使用正则表达式过滤参数。使用正则表达式过滤可能造成注入的符号,如' --等

(3)、在页面输入参数时也进行字符串检测和提交时进行参数检查,同样可以使用正则表达式,不允许特殊符号出现。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值