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