MyBatis Xml映射文件之字符串替換方式

MyBatis Xml映射文件字符串替換

字符串替換

默認情況下,使用 #{} 格式的語法會導致 MyBatis 創建 PreparedStatement 參數占位符並安全地設置參數(就像使用 ? 一樣)。 這樣做更安全,更迅速,通常也是首選做法,不過有時你就是想直接在 SQL 語句中插入一個不轉義的字符串。

比如,像 ORDER BY,你可以這樣來使用:

ORDER BY ${columnName}

這裡 MyBatis 不會修改或轉義字符串。

當 SQL 語句中的元數據(如表名或列名)是動態生成的時候,字符串替換將會非常有用。

舉個例子

如果你想通過任何一列從表中 select 數據時,不需要像下面這樣寫:

@Select("select * from user where id = #{id}")
User findById(@Param("id") long id);
 
@Select("select * from user where name = #{name}")
User findByName(@Param("name") String name);
 
@Select("select * from user where email = #{email}")
User findByEmail(@Param("email") String email); 
// and more "findByXxx" method

可以隻寫這樣一個方法:

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);

其中 ${column} 會被直接替換,而 #{value} 會被使用 ? 預處理。 因此你就可以像下面這樣來達到上述功能:

User userOfId1 = userMapper.findByColumn("id", 1L);
User userOfNameKid = userMapper.findByColumn("name", "kid");
User userOfEmail = userMapper.findByColumn("email", [email protected]);

這個想法也同樣適用於用來替換表名的情況。

提示:用這種方式接受用戶的輸入,並將其用於語句中的參數是不安全的,會導致潛在的 SQL 註入攻擊,因此要麼不允許用戶輸入這些字段,要麼自行轉義並檢驗。

Mybatis中字符串替換問題

默認情況下,使用#{}格式的語法會導致MyBatis創建預處理語句屬性並以它為背景設置安全的值(比如?)。這樣做很安全,很迅速也是首選做法!

有時隻想直接在SQL語句中插入一個不改變的字符串.比如,像ORDER BY,你可以這樣來使用:ORDER BY ${column}

這裡MyBatis不會修改或轉義字符串。

重要:接受從用戶輸出的內容並提供給語句中不變的字符串,這樣做是不安全的。這會導致潛在的SQL註入攻擊,因此你不應該允許用戶輸入這些字段,或者通常自行轉義並檢查!

錯誤方式:

ORDER BY fupdated ${sort, jdbcType=VARCHAR}, fcreated ${sort, jdbcType=VARCHAR}

正確方式:

ORDER BY fupdated ${sort}, fcreated ${sort}

前提條件:請對sort進行必要驗證,防止sql攻擊問題!

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: