mybatis中#跟$有什么区别

动态 SQL 是 mybatis 的强大特性之一,mybatis 在对 sql 语句预编译前,会对 sql 进行动态解析,解析为一个 BoundSql 对象,在动态 SQL 解析阶段,#和$的不同:

#可以防止sql注入.先把sql中使用#的地方变成?占位符,再设置参数值

insert into students id = #{id};//id=2

#{}在动态解析后

insert into students id = ?;

再设置参数值,#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号

insert into students id = "2"; //id=2

$会导致sql注入,可以拼接sql

insert into students id = ${id};

在 动 态 解 析 后 , {}在动态解析后, 将传入的数据直接显示生成在sql中。

insert into students id = 2;//id=2

MyBatis启用了预编译功能,所以防止了sql注入。

MyBatis是如何做到SQL预编译的呢?
我们都知道的,是JDBC中的PreparedStatement类在起作用,PreparedStatement是Statement的子类,使用PreparedStatement不仅能够防止sql注入,而且比Statement提高了效率。

值得一提的是PreparedStatement对#和 $ 都支持,而Statement只支持$.

在Mybaits的6个执行器中BatchExecutor批处理执行类,比较突出,这里就通过它当中的PrepareStatement和Statement来讲原理。

https://blog.csdn.net/qq_37432174/article/details/97567320

1. JDBC中Statement的批处理原理图
对于Statement来说,只要SQL不同,就会产生新编译动作,Statement不支持问号“?”参数占位符。
在这里插入图片描述

2.JDBC中PrepareStatement的批处理原理图
对于PrepareStatement,只要SQL相同,就只会编译一次,如果SQL不同呢?此时和Statement一样,会编译多次。PrepareStatement的优势在于支持问号“?”参数占位符,SQL相同,参数不同时,可以减少编译次数至一次,大大提高效率;另外可以防止SQL注入漏洞。
在这里插入图片描述
自我理解:
JDBC中Statement和 PrepareStatement的批处理区别:
因为Statement不支持问号“?”参数占位符替换,而PrepareStatement
支持问号“?”参数占位符替换,所以有时候同一sql语句会因为参数的不同而成不同的语句,例如:

insert into students(id) values(1);
insert into students(id) values(1);
insert into students(id) values(2);
insert into students(id) values(3);

上面的4个Sql,无论是Statement,还是PrepareStatement,对Sql都编译3次。因为其中第1、2条Sql是完全相同的,只会编译1次。

insert into students(id) values(?); // id=[1,2,3]

对于PrepareStatement,支持问号“?”占位符,向数据库中插入id=[1,2,3]三条记录,对Sql只编译1次,由于减少了编译次数,大幅提高了效率。

Statement不支持问号“?”占位符,向数据库中插入id=[1,2,3]三条记录,只能写成下面这样。

insert into students(id) values(1);
insert into students(id) values(2);
insert into students(id) values(3);

由于Sql不同,所以编译3次,效率较低。

在加入addBatch()前,没有加入参数,语句不会因为参数的不同而显得是不同的sql语句。
只要SQL不同,就会产生新编译动作,
如果是Preparestatement,但是参数可能不同,也是同一条SQL,这样就不需要重复创建PrepareStatement。
如果是Statement,但是参数可能不同,就不是同一条SQL,这样就需要重复创建Statement。

BatchExecutor的批处理原理图
BatchExecutor的批处理,和JDBC的批处理,主要区别就是BatchExecutor维护了一组Statement批处理对象,它有自动路由功能,sqlA、sqlB、sqlC代表不同的SQL。(Statement或Preparestatement)。

可以减少网络交互次次数,通过源码可以发现批处理中最佳时间就是同样的sql要一起执行,不要存在不同sql间隔这样的场景出现

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偷偷学习被我发现

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值