MyBatis中${}与#{}区别
#{}
预编译SQL,类似于JAVA的预编译,例如:
String sql = "insert into info(name,age) values(?,?)";
PreparedStatement sta = con.prepareStatement(sql);
sta.setString(1, “张三”);
sta.setInt(2, 10);
只不过默认情况下会把参数当做字符串而自动添加一个双引号,例如:order by #id#,当传入的值是10时则为order by “10”。
凡是用到table、column名字的地方都不能用#,例如:insert into/select/delete/order by等这些后面是紧跟table名字和column名字的,这些名字是不允许添加引号的。
优点在于:防止SQL注入。
${}
不会预编译,原样输出,不会额外添加任何符号。例如:order by ${id},当传入的值是10时则为order by 10。
缺点:可能发生SQL注入问题。
#{}扩展JdbcType
在执行SQL时MyBatis会自动通过对象中的属性给SQL中参数赋值,它会自动将Java类型转换成数据库的类型。而一旦传入的是null 程序就无法准确判断这个类型应该是什么(是Integer?是VARCHAR?还是别的?),就有可能将类型转换错误从而报错。加入jdbcType正是为了解决这样的报错。
方向:从Java类型转变成数据库类型。
BIT | FLOAT | CHAR | TIMESTAMP |
TINYINT | REAL | VARCHAR | BINARY |
SMALLINT | DOUBLE | LANGVARCHAR | VARBINARY |
INTEGER | NUMBERIC | DATE | LOANGVARBINARY |
BIGINT | DECIMAL | TIME | NULL |
OTHER | BLOB | CLOB | BOOLEAN |
UNDEFINED | NVARCHAR | NCHAR | NCLOB |
CURSOR |
|
|
|
#{}扩展javaType
说白了,就是从数据库中取出记录后,由于数据库的数据类型与JAVA的数据类型不一致,需要针对特定数据的特定数据类型来指定对应的JAVA类型,这就是javaType。
JDBCType JavaType
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
BOOLEAN boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
DISTINCT mapping of underlying type
STRUCT Struct
REF Ref
DATALINK java.net.URL