MyBatis-映射文件03-两种取值方法(# or $)
#{}:可以获取map中的值或者POJO对象属性的值
${}:可以获取map中的值或者POJO对象属性的值
区别:
#{}:是以预编译的形式设置到sql语句中;PreparedStatement,可以防止sql注入
${}:取出的值直接拼接在sql语句中;会有安全问题
示例:
sql:
select id,last_name,email,gender from tbl_employee where id = ${id} and last_name = #{lastName}
我们调用方法执行该sql,可以发现在控制台输出:
Preparing: select id,last_name,email,gender from tbl_employee where id = 1 and last_name = ?
可以看出使用 $ 取值是直接将值拼接到sql语句中,这样会存在sql注入的安全问题,因此大多数情况下都应该使用 # 来取值
但是,在某些情况下,比如原生sql不支持占位符的地方,例如分表查询,以部分表名为参数,要使用 $ 来取值
示例:
sql:
select id,last_name,email,gender from #{tablename}_employee where id = ${id} and last_name = #{lastName}
此时用#取表名的值会出现sql语法异常错误,而应该使用$来取值
#{}更丰富的用法:
规定参数的一些规则:javaType、jdbcType、mode(存储过程)、numericScale、resultMap、typehandler、jdbcTypeName、expression(未来准备支持的功能)
jdbcType:通常需要在某种特定的条件下被设置
当我们的数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理,比如Oracle数据库(报错),如果向Oracle数据库插入null,会报错为:jdbcType OTHER:无效的类型,因为mybatis对所有的null都映射的是jdbc的OTHER类型,Oracle不能正确处理
解决办法:
1.#{email,jdbcType=NULL}
insert into employee(Employee_ID,last_name,email) values(#{id},#{lastName},#{email,jdbcType=NULL})
2.由于全局配置中:jdbcTypeForNull默认为OTHER,Oracle不支持,修改全局配置文件的 jdbcTypeForNull为NULL
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
本文探讨了MyBatis中#{}和${}两种取值方法的使用及区别。#{}以预编译方式设置SQL语句,能防止SQL注入,而${}直接拼接SQL,存在安全隐患。建议一般情况使用#{},但在如分表查询等特殊场景下需使用${}。此外,介绍了#{}的更多高级用法,如jdbcType设置,以及如何处理Oracle数据库对null值的特殊处理问题。"
107460370,9298436,洛谷P1135奇怪电梯题解:C++ BFS解析,"['算法', 'C++', '编程题解', 'BFS', '洛谷']
435

被折叠的 条评论
为什么被折叠?



