mybatis#号和$的区别是什么,想必大家在面试过程中或多或少都会遇到过这个问题吧!
当面试官问到这个问题的时候,是不是答完:“#号可以防止sql注入,$不可以防止sql注入”。就草草了事了呢?
这么回答正确,没问题!可你有没有想过这么简单的回答有什么意义呢?只能证明你知道答案,对于你个人的能力却毫无展现。
这时对于一个有几年工作经验的你,心中是否在想这么简单的问题还要问吗?是面试官在怀疑你的能力,还是面试官不知道问什么?
为了避免一句话就答完这个问题的尴尬,同时又能展现你的能力,阿灯为大家准备了如下参考。
1、谈发现
在日常开发中,我们难免会根据控制台或日志打印出的sql语句进行验证和调试。但是往往我们在控制台看到的sql语句,并不是完整带参数的语句而是带有?号占位符的。如下:
mybatis语句:select id from user where name=#{name}
select id from user where name=?
我们复制语句后,想要单独执行sql语句,这时就需要手动的将占位符替换成相应的参数。如果遇到参数过多的情况,那么,我们手动替换时不仅会感到很繁琐,同时也会很浪费时间。这时我们就会想,能不能在控制台打印出不带占位符的完整sql语句,下面阿灯给大家提供点打印完整sql的方式:
可以通过P6Spy跟踪sql的执行情况,只需要添加maven依赖和一个spy.properties配置文件即可
maven依赖如下
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>2.1.4</version>
</dependency>
还有一种简单的方式,在IDEA中安装MyBatis Log Plugin 这时就可以通过控制台看到不带占位符的完整sql语句了。如下:
select id from user where name='admin'
当然其他方式也有,大家可自行研究。
这时我们发现打印出的sql语句就是带有参数的完整sql语句了。在这种情况下复制调试,是不是很方便呢?
到这里我们就会发现使用${}时,sql语句是按照参数原样拼接的。而使用#{}sql语句的参数上会多出单引号 ‘
2、谈研究
我们在第一步会发现$和#号的sql语句输出结果的参数,有不加单引号和加单引号的区别。
那么阿灯问大家个问题:select * from user where name=${name}这样的语句可以写吗? 不明确的,可以试下。
答案当然是不可以的,那么select * from user where name='${name}'又和select * from user where name=#{name} 有什么区别呢?最终的sql语句不都是在name参数上加了引号了吗?表面上看貌似是,但如果name的值为:admin' or '1'='1,那么最终sql是不是一样呢?
sql的最终结果是:$的sql原样输出,而#号的结果如下:
select * from user where name='admin'' or ''1''=''1'
我们从#号的sql最终结果来看,会发现参数中的单引号都被进行了转义,这时,大家便会想到sql防止sql注入的问题了吧,因此可以说明“#号可以防止sql注入,$不可以防止sql注入”。#号防止sql注入的原理就是对参数及参数中的特殊字符进行了转义,从而达到防止sql注入的效果。
此时,我们回顾下,mybatis的底层是什么?jdbc啊。我们可以联想到jdbc中的Statement对象和 PrepareStatement对象。而mybatis的$符就是对Statement语句进行的封装处理,#号就是对 PrepareStatement语句进行的封装处理。因此达到实现不同效果和目的的。
到这里我们就不难跟踪到上面的单引号是在哪里进行转义的了。我们可以翻看jdbc的源码,由于是参数设置,当然要看set方法了。简单截个图,源码大家还是自己去翻吧setString方法里。
3、谈应用
在实际开发中,我们使用#号的居多,各种条件查询。而$符号也在使用,比如由于数据量的原因,我们将数据进行按业务分表,在表名不同字段相同的情况,为了简化代码量和灵活度采用动态表名的查询
select * from ${tableName}
再如为了灵活排序而使用的 order by ${filedName}等多种情况。
但有一点需要注意,为了保证安全的情况,在使用$时,尽量避免动态字段从客户端显示传递使用。
通过以上的回答和交流,面试官是不是会感觉你不是小白,同时在工作和学习中很用心的一个开发者呢?
采用此种方式介绍的目的,是为了让大家在工作和学习中要善于发现、思考和总结和尝试。运用联想和为什么的方法去定向解决问题。当然文中可能有许多不足之处,望大家指正交流。
扫描或长按下方二维码关注公众号,持久关注阿灯的动态