#{}和${}都可以获取map中的值或者pojo对象属性的值;
sql语句示例:
select * from tbl_employee where id=${id} and last_name=#{lastName}
Preparing: select * from tbl_employee where id=2 and last_name=?
#{}和${}的区别:
#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中;会有安全问题;例如#{}只能取出表中参数位置的值,即id=#{},但如:from #{} 就会出错,或者排序order by #{}也会出错,此时,from或order by后面就需要使用${}来拼接字符串;
所以#{}用来赋值${}用来拼接sql语句
大多情况下,我们去参数的值都应该去使用#{};
原生jdbc不支持占位符的地方我们就可以使用${}进行取值
比如分表、排序。。。;按照年份分表拆分
select * from ${year}_salary where xxx;
select * from tbl_employee order by ${f_name} ${order}
#{}:更丰富的用法:
规定参数的一些规则:
javaType、 jdbcType、 mode(存储过程)、 numericScale、
resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能);
jdbcType通常需要在某种特定的条件下被设置:
在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错);
JdbcType OTHER:无效的类型;因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理;
由于全局配置中:jdbcTypeForNull=OTHER;oracle不支持;两种办法
1、#{email,jdbcType=NULL};
2、全局配置文件中配置全局变量:<settings><setting name="jdbcTypeForNull" value="NULL"/></settings>
sql注入
sql注入实例:
预编译
又称为预处理,是做些代码文本的替换工作。是整个编译过程的最先做的工作;
处理#开头的指令;
预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理。
jdbcType
Java对象中的类型和数据库中类型的对应:
mybatis包中对应的类时JdbcType.java,且是枚举类型
1 JDBC Type Java Type
2 CHAR String
3 VARCHAR String
4 LONGVARCHAR String
5 NUMERIC java.math.BigDecimal
6 DECIMAL java.math.BigDecimal
7 BIT boolean
8 BOOLEAN boolean
9 TINYINT byte
10 SMALLINT short
11 INTEGER INTEGER
12 BIGINT long
13 REAL float
14 FLOAT double
15 DOUBLE double
16 BINARY byte[]
17 VARBINARY byte[]
18 LONGVARBINARY byte[]
19 DATE java.sql.Date
20 TIME java.sql.Time
21 TIMESTAMP java.sql.Timestamp
22 CLOB Clob
23 BLOB Blob
24 ARRAY Array
25 DISTINCT mapping of underlying type
26 STRUCT Struct
27 REF Ref
28 DATALINK java.net.URL[color=red][/color]