MyBatis 中使用 parameterType 向 SQL 语句传参,parameterType支持的类型可以是基本类型int,String,HashMap和java自定义类型。

在SQL中引用这些参数的时候,可以使用两种方式:

  • #{parameterName}

  • ${parameterName}

首先,我们说一下这两种引用参数时的区别,使用#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,并自动加上’’,例如传入参数是“Smith”,那么在下面SQL中:

Select * from emp where name = #{employeeName}

使用的时候就会转换为:

Select * from emp where name = 'Smith';

同时使用${parameterName}的时候在下面SQL中

Select * from emp where name = ${employeeName}

就会直接转换为:

Select * from emp where name = Smith

简单说**#{}是经过预编译的,是安全的**。而**${}**是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入

#{} 这种取值是编译好SQL语句再取值
${} 这种是取值以后再去编译SQL语句

下面我们用一个实际的例子看看分别使用和是否可以防止SQL注入。

首先是使用#{}:

<!-- 使用#{} -->
<select id="selectUser" parameterType="String" resultType="com.mybatis.po.MyUser">select * from user where account = #{account} and password = #{password}
</select>

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

// 使用#{} 正常传参
Map<String, Object> parameter = new HashMap<>();
parameter.put("account", );
parameter.put("password", password);
MyUser mu = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser", parameter);
System.out.println("返回结果:" + mu);// 使用#{} 拼接传参
Map<String, Object> parameter_1 = new HashMap<>();
parameter_1.put("account", "201301001");
parameter_1.put("password", "111111" + "or account = 'admin' ");
MyUser mu_1 = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser", parameter_1);
System.out.println("返回结果:" + mu_1);

结果如下:

DEBUG [http-nio-8080-exec-5] - ==>  Preparing: select * from user where account = ? and password = ?
DEBUG [http-nio-8080-exec-5] - ==> Parameters: 201301001(String), 111111(String)
DEBUG [http-nio-8080-exec-5] - <==      Total: 1
返回结果:MyUser [id=17, account=201301001, password=111111, name=蒙奇D路飞]
DEBUG [http-nio-8080-exec-5] - ==>  Preparing: select * from user where account = ? and password = ?
DEBUG [http-nio-8080-exec-5] - ==> Parameters: 201301001(String), 111111 or account = 'admin' (String)
DEBUG [http-nio-8080-exec-5] - <==      Total: 0
返回结果:null

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

DEBUG [http-nio-8080-exec-5] - ==>  Preparing: select * from user where account = ? and password = ?
DEBUG [http-nio-8080-exec-5] - ==> Parameters: 201301001(String), 111111 or account = 'admin' (String)
DEBUG [http-nio-8080-exec-5] - <==      Total: 0
转换为实际的SQL语句:select * from user where account = '201301001' and password = '111111 or account = 'admin''

现在是使用**${}**:

<!-- 使用${} -->
<select id="selectUser2" parameterType="String" resultType="com.mybatis.po.MyUser">select * from user where account = ${account} and password = ${password}
</select>

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

// 使用${} 正常传参
Map<String, Object> parameter = new HashMap<>();
parameter.put("account", "201301001");
parameter.put("password", "111111");
MyUser mu = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser2",parameter);
System.out.println("返回结果:" + mu);// 使用${} 拼接传参
Map<String, Object> parameter2 = new HashMap<>();
parameter2.put("account", "201301001");
parameter2.put("password", "111111" + " or account = 'admin' ");
MyUser mu2 = ss.selectOne("com.mybatis.mapper.UserMapper.selectUser2", parameter2);
System.out.println("返回结果:" + mu2);

结果如下:

DEBUG [http-nio-8080-exec-18] - ==>  Preparing: select * from user where account = 201301001 and password = 111111
DEBUG [http-nio-8080-exec-18] - ==> Parameters:
DEBUG [http-nio-8080-exec-18] - <==      Total: 1
返回结果:MyUser [id=17, account=201301001, password=111111, name=蒙奇D路飞]
DEBUG [http-nio-8080-exec-18] - ==>  Preparing: select * from user where account = 201301001 and password = 111111 or account = 'admin'
DEBUG [http-nio-8080-exec-18] - ==> Parameters:
DEBUG [http-nio-8080-exec-18] - <==      Total: 2
返回结果:[MyUser [id=1, account=admin, password=111111, name=管理员], MyUser [id=17, account=201301001, password=111111, name=蒙奇D路飞]]

很明显,使用 ${} 将参数拼接后在编译成SQL语句,不能防止SQL注入,查询出了有关account=admin的额外信息,这是很危险的。

Mybatis中的#{}用于传递查询的参数,用于从dao层传递一个string参数过来(也可以是其他参数),select * from 表名 order by age=#{age}

Mybatis会把这个参数转换成一个字符串。select * from 表名 order by age=“age” 相当于jdbc中的预编译,安全。

而${}一般用于order by的后面,Mybatis不会对这个参数进行任何的处理,直接生成了sql语句。例:传入一个年龄age的参数,select * from 表名 order by ${age}

Mybatis生成的语句为 select * from 表名 order by age Mybatis不会对$传递的参数做任何处理,相当于jdbc中的另外一种编译方式。

一般我们使用#{},不使用${},原因:

会引起sql注入,${}会直接参与sql编译。会影响sql语句的预编译。

MyBatis中的#和$之间的区别相关推荐

  1. java中separator_java - File.separator和路径中的斜杠之间的区别

    java - File.separator和路径中的斜杠之间的区别 在Java Path-String中使用/和普通的File.separator有什么区别? 与双反斜杠相比,/平台独立似乎不是原因, ...

  2. 在循环之前或循环中声明变量之间的区别?

    本文翻译自:Difference between declaring variables before or in loop? I have always wondered if, in genera ...

  3. mybatis中association 和collection 的区别

    mybatis中association 和collection 的区别:https://zhidao.baidu.com/question/1240407172484106299.html 两个实体类 ...

  4. 在mybatis中resultMap与resultType的区别

    MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap resultType是直接表示返回类型的,而resultMap则是对外部ResultM ...

  5. mybatis中resultType和resultMap的区别

    MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap resultType是直接表示返回类型的,而resultMap则是对外部ResultM ...

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

    在mybatis中#和$的主要区别是:#传入的参数在SQL中显示为字符串,#方式能够很大程度防止SQL注入:$传入的参数在SQL中直接显示为传入的值,$方式无法防止SQL注入. 1.传入的参数在SQL ...

  7. python中的编码和解码_Python中“is”和“==”之间的区别,以及编码和解码,与

    Python中'is'和'=='的区别,以及编码与解码 Python中'=='和'is'的区别 (1)Python中'==' Python中'==比较变量的值,如果值相同返回True,如果不同返回Fl ...

  8. Mybatis中的resultType与resultMap区别

    都可以返回一种数据类型,比如String,Long,自定义的Person类等: MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候 ...

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

    最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, 比如说用#{},和 ${}传参的区别,  使用#传入参数是,sql语句解析是会加上"&qu ...

最新文章

  1. ANTLR 4的C#实例
  2. sdn专线架构是怎样的?如何工作?——Vecloud
  3. SpringCloud教程-消息总线Bus 服务端(server)刷新(SpringCloud版本Greenwich.SR4)
  4. 五十八、如何对一个数进行分解质因数
  5. Mybatis实现多表关联多条件查询
  6. vscode正则表达式替换php数组,vscode正则替换
  7. html点击关闭代码,怎样开放和关闭html代码?
  8. 搭建Servlet在线视频
  9. 阿里P8架构师谈:Dubbo的详细介绍、设计思路、以及4大适用场景
  10. tomcat linux环境变量,linux系统为什么需要配置tomcat环境变量
  11. java 虚拟内存不够,java虚拟内存不足
  12. BZOJ 4143: [AMPPZ2014]The Lawyer( sort )
  13. C语言控制台窗口界面编程:用printf在终端打印一个GUI窗口
  14. Linux下Oracle中sqlplus上下键乱码问题
  15. 装饰模式--私人定制冬装夏装
  16. idea 使用exe4j生成exe文件并且附带jre运行环境(亲测有效)
  17. 科技百咖 | 天威诚信:韶光与共,不负前路
  18. CTF-RSA分解模数N
  19. 如何写出高质量的技术博客
  20. python哈姆雷特词频统计_《哈姆雷特与三国演义》词频统计,Hamlet,和

热门文章

  1. oracle sqlloader 的简单使用
  2. carmaker主要模块使用说明
  3. 手把手教你安装GNS3
  4. Linux显卡驱动安装
  5. [PC系统软件] 『新版小A』Avast! Premier 高级版 8.0.1483.72 完美破解版【可正常更新病毒库】
  6. 电子学会青少年软件编程 Python编程等级考试一级真题解析(选择题)2022年3月
  7. 如何在所有用户的桌面创建快捷方式
  8. Linux / Windows Subsystem for Linux (WSL) 安装 ADB (Android Debug Bridge,Android 调试桥)
  9. Layuimini一个适合懒人的开源代码-相关使用
  10. 硬盘分区失败丢失数据如何恢复