为什么要有#和$?
Spring和MyBatis的#和$都是为了解决配置文件中的属性值问题而引入的。
在Spring中,$符号表示属性占位符,可以将属性文件中的属性值替换到Spring配置文件中的属性值中;而#{}符号则表示SpEL表达式占位符,可以通过表达式来计算属性值。
在MyBatis中,#符号表示参数占位符,可以防止SQL注入攻击;而$符号则表示文本替换符,直接将变量替换到SQL语句中,可能存在SQL注入风险。
在Spring和MyBatis中的#和$有什么相同点和不同点?
共同点:
- 在Spring和MyBatis中,#和$都可以用于参数占位符,用于将参数值动态地传递给SQL语句。
区别点:
- 在Spring中
- #是SpEL表达式占位符,可以通过表达式来计算属性值;
- $是属性占位符,可以将属性文件中的属性值替换到Spring配置文件中的属性值中。
- 在MyBatis中
- #是预编译处理,可以有效防止SQL注入攻击;
- $是字符串替换,不具备防止SQL注入攻击的功能。
- 在MyBatis中,#通常用于替换参数,$通常用于替换列名或表名。
在Spring中SpEL表达式有哪些?最重要的是哪些?
Spring Expression Language(SpEL)是Spring框架中的一种表达式语言,可以在运行时计算表达式的值。它支持在Spring框架中访问和操作对象图,包括Spring bean和属性文件中的属性。
SpEL表达式可以通过以下方式使用:
- 字面值:包括字符串,数字,布尔值和null
- 引用对象:包括Spring bean和静态类的引用
- 属性访问:访问对象的属性
- 方法调用:调用对象的方法
- 运算符:支持算术,比较和逻辑运算符
- 表达式列表:支持在表达式中使用列表,集合和数组
- 正则表达式:支持正则表达式
- 赋值:支持将值赋给对象的属性
其中最重要的SpEL表达式是引用对象和属性访问。
它们使得我们可以轻松地在Spring框架中访问和操作对象图,而不需要编写复杂的Java代码。
为什么MyBatis中的#能够防止恶意的注入攻击?
在MyBatis中使用#可以防止SQL注入攻击的原因是,#号会将传入的参数视为一个完整的值,并对这个值进行预编译处理,最终在将其绑定到SQL语句中时,会将其转换成一个占位符,然后再与SQL语句进行拼接。因此,无论传入的参数是什么,都不会对SQL语句造成影响。
举个例子:#{name}传入的是'admin' or 1=1',其最终会转换成什么传入SQL语句呢?
传入入的值为'admin' or 1=1'
,在使用#
时,MyBatis会将其转义为'admin\' or 1=1';
传入SQL语句后,数据库会将其视为一个普通的字符串,而不会将or 1=1
解析成一个条件语句。
因此,使用#
可以有效地防止SQL注入攻击。
配置文件中使用的#与占位符时使用有什么区别?
MyBatis配置文件中,如果您看到类似${...}
的语法,那么它与Spring配置文件中的${...}
语法具有相同的目的:从外部属性文件中引用属性值。这里的$
符号用于从属性文件中获取配置值。请注意,这与MyBatis在SQL映射文件中使用#{...}
和${...}
作为参数占位符的语法是不同的。
在MyBatis配置文件(mybatis-config.xml
)中,您可以使用${...}
语法引用外部属性文件中的值
<dataSource type="POOLED">
<property name="driver" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
这个示例中的${db.driverClassName}
、${db.url}
、${db.username}
和${db.password}
用于从外部属性文件中获取数据库配置信息。这种方法允许您在不修改应用程序代码的情况下轻松更改数据库配置。
请注意,这里的$
与MyBatis中的#{...}
和$
参数占位符是不同的。在MyBatis SQL映射文件中,#{...}
用于传递预编译参数,而${...}
用于直接插入SQL参数。
总结
在MyBatis中,尽量使用#解决配置文件中的属性值问题,因为其能防止恶意注入攻击;但对动态拼接SQL语句时,可能需要使用$
符号进行占位符替换。
在Spring中,$使用简单方便,而#可以进行更复杂的运算和处理。