MyBatis中#和$前肘和后肘的区别详解解

零、引言使用 #{name} 的时候,MyBatis会进行预编译,防止SQL注入的问题(官方话)用一个通俗一点的例子来解释,比如有如下MyBatis的SQL语句21、#{}和${}的区别.png一、最正确的用法&select id="find"&
... where name = #{name} order by ${columnName}
&/select&说明:如果name的类型为String值为LCF,columnName的类型为String值为 id上述SQL翻译结果是:... where name = 'LCF' order by id1. #{name} 会根据传入数据的类型进行预编译,所以在生成SQL的时候自动加上了单引号。2.${columnName} 会直接将结果替换进来。二、反例说明&select id="find"&
... where name = ${name} order by #{columnName}
&/select&说明:基本类型和值如上所述,该SQL翻译出来的结果是什么?... where name = LCF order by 'id'仔细看LCF是没有单引号引起来的,反倒是 id 被单引号括起来了。三、结论#会进行预编译,防止SQL注入。$会被直接进行字符替换,容易造成SQL注入。#####################LCF####################################
阅读(...) 评论()1034人阅读
mybatis(1)
mysql(23)
首先通过下面两条sql及打印的执行sql,清楚明了的看一下它们的区别:
&select id="selectUserInfo" parameterType="java.util.Map" resultType="java.util.Map"&
userId=${id} password=#{pwd}
假设入参传入的是1,打印执行sql如下:
Preparing:select * from user where id=1 and password=111111
&select id="selectUserInfo" parameterType="java.util.Map" resultType="java.util.Map"&
userId=#{id} and password=#{pwd}
同样入参传入1,打印的执行sql如下:
Preparing:select * from user where id=? and password=?
Parameters:1(String),111111(String)
MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;执行时,如果入参为#{}格式的,将入参替换编译好的sql中的占位符“?”;如果入参格式为${},则直接使用编译好的SQL就可以了。因为SQL注入只能对编译过程起作用,所以使用#{}入参的方式可以很好地避免了SQL注入的问题。
mybatis预编译底层实现原理
MyBatis是如何做到SQL预编译的呢?其实在框架底层,是JDBC中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的SQL语句。这种“准备好”的方式不仅能提高安全性,而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。
#{}:相当于JDBC中的PreparedStatement
${}:是输出变量的值
简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。
番外(sql注入)
还是以上面的两条sql为例,入参id的值传入“1 or userId=2”,入参pwd的值传入“111111”。以#{}格式传入入参后的执行sql:
select * from user where userId=”1 or userId=2” and password = “111111”;
以${}格式传入入参后的执行sql:
select * from user where userId=1 or userId=2 and password = 111111;
很显然,以${}格式传入入参后的执行sql打乱了我们的预期sql格式及查询条件,从而实现sql注入。所以,除了order by 等需要传入数据库字段等的入参使用${},其他的尽量使用#{}。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:113006次
积分:1759
积分:1759
排名:千里之外
原创:66篇
转载:37篇
评论:10条
(1)(4)(2)(4)(4)(4)(5)(1)(1)(4)(7)(3)(7)(5)(18)(2)(7)(1)(2)(19)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by &111&, 如果传入的值是id,则解析成的sql为order
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,& 如果传入的值是id,则解析成的sql为order
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
本文已收录于以下专栏:
相关文章推荐
最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下,
比如说用#{},和 ${}传参的区别,
使用#传入参数是,sql语句解析是会加上...
#相当于对数据 加上 双引号,$相当于直接显示数据
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111...
MyBatis/Ibatis中#和$的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时...
MyBatis mapper文件中的变量引用方式#{}与${}的差别
        默认情况下,使用#{}语法,MyBatis会产生PreparedStatement语句中,并且安全的设置P...
SSM =SpringMVC +Spring +Mybatis
需要的jar包链接链接:/s/1c10kx7U 密码:1u18
我们先来看看文件结构图
在ssm搭建框架时,根据我们的需求会用到各种jar包,下面就简单介绍一下我在搭建框架时常用的各种jar的作用:
1:junit-jar 
   测试的时候使用
2:spring-context.jar...
这几天一直在整合SSM框架,虽然网上有很多已经整合好的,但是对于里面的配置文件并没有进行过多的说明,很多人知其然不知其所以然,经过几天的搜索和整理,今天总算对其中的XML配置文件有了一定的了解,所以拿...
在sql配置中比如in(#rewr#) 与in ($rewr$)
在Ibatis中我们使用SqlMap进行Sql查询时需要引用参数,在参数引用中遇到的符号#和$之间的区分为,#可以进行与编译,进行类...
1、前台JSP页面
// 配置路径
require.config({
echarts: '${ctx}/plugins...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)<span style="color: #.$ 不安全 底层实现是Statement对象
select * from student where id=${id}
如果我们id传入的是11 编译之后
select * from student where id=11
# 安全 底层实现是PreparedStatement对象
select * from student where id=#{id}
如果我们id传入的是11 编译之后
select * from student where id=?
MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;
执行时,如果传入参数为#{}格式的,将传入参数替换编译好的sql中的占位符“?”;
如果传入参数格式为${},则直接使用编译好的SQL就可以了。
因为SQL注入只能对编译过程起作用,所以使用#{}传入参数的方式可以很好地避免了SQL注入的问题。
<span style="color: #.在sql语句需要排序的时候
order by ${id}
只有在需要排序的时候 使用$&
其他时候能用#绝对不用$
阅读(...) 评论()Mybatis中#与$的区别
Mybatis中#与$的区别
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语句的预编译。

我要回帖

更多关于 c 区别 详解 的文章

 

随机推荐