各位大佬光临寒舍,希望各位能赏脸给个三连,谢谢各位大佬了!!!
目录
1.有无预编译
优点
缺点
2.SQL执行的快慢
3.能否被SQL注入
4.参数输入方式
5.总结
1.有无预编译
#{}是有预编译的而${}是没有预编译的,那什么是预编译,预编译又有什么优缺点呢?在了解这个之前,预编译进行的步骤:
它会将SQL语法进行解析再进行SQL优化再进行编译,最后才给到数据库进行执行。
优点
但是当有多个SQL语句的时候,预编译就会显得很慢,所以预编译的SQL会被加入到一个缓存区,当只有?处的参数变化时,会直接从缓存区中拿到SQL,让SQL进行执行,这样它的速度就会加快很多。并且执行了SQL优化后,SQL语句就不会因为SQL注入导致数据库被破坏。
缺点
在执行多个不仅仅是参数不同的SQL时每次都需要重新预编译,导致速度不如不预编译的快。
2.SQL执行的快慢
就像上面说的有无预编译的区别,#{}在执行多个仅在参数有所不同的SQL时仅仅在预编译时进行编译省去了SQL的编译,执行效率就更高,而${}则只是一个字符串拼接,每次都要把SQL语句给到数据库进行编译处理再执行,对于多个仅在参数有所不同的SQL时效率低,而在不仅仅是参数不同的SQL语句中${}更加有效率。但是当今的项目大部分都是执行多个仅在参数有所不同的SQL,所以大部分情况都是#{}更有效率。
3.能否被SQL注入
因为#{}在预编译阶段就进行了SQL的优化,导致它不仅仅是SQL的拼接,而是替换?处的参数,所以它不能被SQL注入从而使数据库受到损害。而${}只是对数据的单纯拼接,所以它是会被SQL注入的,就比如以下语句:
@Select("select * from student1 where id<=${id}")public List<StudentInfo> getId(Integer id) ;
我们可以直接输入以下内容来获取所有的用户信息
1 or 1=1
也可以输入以下内容直接删除数据库
1;drop database mybatis;
所以${}是比较危险的。
4.参数输入方式
#{}会根据所对应的参数选择加不加“”,如String类型就会加“”,而Integer类型就不会加引号。而${}在所有情况下都不会加引号。如图:
#{}会进行参数带入
${}直接以字符形势加入字符,这时候就会报错,外面需要自己在参数外加‘’
所以在一般情况下#{}方便很多,我们不需要在参数为String时外面添加引号,但是也有特殊情况,那就是我们需要String类型但是我们不想加引号,如自己选定降序,升序排序。但是我们又怕SQL注入,所以一般对于这种情况我们都会对前端或者后端做出交互限制,让前端发送数字,或者后端把前端的字符转成数字,再以键值对的形式输入参数,这样就算有别的数据也会被判定为不合法。
5.总结
总的来说,#{}的用途更加广泛,也更加安全,它们俩的区别概括一下也就三个点:
1.#{}有预编译${}无预编译
2.#{}写入参数是占位的方式不会被SQL注入,安全,${}是直接以字符的形式写入参数,会被SQL注入,不安全。
3.一般情况的SQL#{}都能完成,但是对于一些特殊场景比如排序,字段名作为参数等情况需要使用${},但是也要注意使用方法。
这里其实还有一个就是模糊查询,正常情况下需要用${},因为例如say like '%hi%',这样的查询我们只能用'%${hi}%',这样的形式来注入参数,而刚好MySQL有个concat拼接字符串的函数,所以我们可以直接使用concat来完成如 say like concat('%',#{hi},'%')。那我们今天就讲到这吧。有到时候和各位说再见了。在这之前:
制作不易,望各位大佬赏个脸,给个三连吧!!谢谢各位大佬了!!!