1.4 Mybatis中占位符#与$的区别

1.4 占位符#与$的区别

在mybatis中,#$的都可以起到变量替换的作用,但是二者的使用场景却是截然不同的。

"#{}"的作用主要是替换预编译语句(PrepareStatement)中的占位符?,例如xml映射文件中,有以下insert语句

<insert id="insert" parameterType="User">
    INSERT INTO user (name) VALUES (#{name});
</insert>

打印的sql日志如下所示:

16:00:00.691 [main] DEBUG com.tianshouzhi.dragon.common.mappers.UserMapper.insert - ==>  Preparing: INSERT INTO user (name) VALUES (?);
16:00:00.750 [main] DEBUG com.tianshouzhi.dragon.common.mappers.UserMapper.insert - ==> Parameters: tianshozhi(String)

​在第1行日志中,可以看到#{name}被替换成了占位符”?”,熟悉jdbc编程的同学,这里使用的肯定是预编译的PrepareSatement。

​而第2行日志显示了最终要替换这个占位符的参数值是字符串类型的"tianshouzhi"。

$

$符号的作用是直接进行字符串替换。

<insert id="insert" parameterType="User">
    INSERT INTO user (name) VALUES ('${name}');
</insert>

效果

16:00:58.642 [main] DEBUG com.tianshouzhi.dragon.common.mappers.UserMapper.insert - ==>  Preparing: INSERT INTO user (name) VALUES ('tianshozhi');
16:00:58.663 [main] DEBUG com.tianshouzhi.dragon.common.mappers.UserMapper.insert - ==> Parameters:

可以看到在sql日志中,#{name}被直接替换成了"tianshouzhi"。

$与#的区别

对于这二者的区别,mybatis官方文档也有相关描述,大致意思与前面的描述相符:

AD2A6C1C-00E5-4589-B380-6E60869B5AD4.png

值得我们注意的是:使用${}存在SQL注入的风险。

​ 例如上面插入insert语句中的name变量,假设是用户注册时填写的,有一个恶意用户,故意将name填写为:tianshouzhi'),('wangxiaoxiao

此时对于使用#{name}情况:

INSERT INTO user (name) VALUES (#{name});

mybatis首先将其#{name}替换成占位符"?",然后用 tianshouzhi'),('wangxiaoxiao 来替换"?",因此用户名就是tianshouzhi'),('wangxiaoxiao

而对于使用${name}的情况:

INSERT INTO user (name) VALUES ('${name}');

由于是直接替换字符串,此时sql变成如下所示:

INSERT INTO user (name) VALUES ('tianshouzhi'),('wangxiaoxiao');

这是mysql的批量插入语法,相当于在数据库中插入了2条记录。

因此在实际开发中,对于用户填写的变量值,我们一定要尽量使用#{},不要轻易使用${}。

典型误解

部分人认为#{}可以防止SQL注入,因此其使用的是jdbc编程中的PrepareSatement。而${}不可以防止SQL注入,因此使用的Satement。

事实上,默认情况下,在mybatis中,#{}、和${},使用的都是PrepareSatement。请读者回看前面两种情况打印出SQL时,前面都有一个Preparing,这就是明显的提示。

事实上<insert><update><delete><select>都有一个statementType属性,取值范围为: STATEMENTPREPAREDCALLABLE 的一个,这会让 MyBatis 分别使用 StatementPreparedStatementCallableStatement

statementType属性的默认值为PREPARED,因此默认的SQL语句都是通过PreparedStatement来执行的。

转载自:http://www.tianshouzhi.com/api/tutorials/mybatis/356

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值