1. 程式人生 > >Mapper對映檔案中的#{}與${}

Mapper對映檔案中的#{}與${}

#{}實現的是向prepareStatement中的預處理語句中設定引數值,sql語句中#{}表示一個佔位符即?。 

  1. <!--根據id查詢使用者資訊 -->  
  2. <select id="findUserById"parameterType="int"resultType="user">  
  3.     select * from user where id =#{id}  
  4. </select>  

使用佔位符#{}可以有效防止sql注入,在使用時不需要關心引數值的型別,mybatis會自動進行Java型別和jdbc型別的轉換。#{}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。說得再通俗一點,當我們使用#{}的時候,發出的sql中,#{}代表的內容會自動被加上“”,而${}是直接把東西取出來直接用舉個例子:

id="liweizhong",#{id}輸出後是"liweizhong",而${value}輸出是liweizhong

${}和#{}不同,通過${}可以將parameterType傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。使用${}不能防止sql注入,但是有時用${}會非常方便,如下的例子:

  1. <!--根據名稱模糊查詢使用者資訊 -->  
  2. <select id="selectUserByName"parameterType="string"resultType="user">  
  3.     select * from user whereusername like '%${value}%'  
  4. </select>  

如果本例子使用#{}則傳入的字串中必須有%號,而%是人為拼接在引數中,顯然有點麻煩,如果採用${}在sql中拼接為%的方式則在呼叫mapper介面傳遞引數就方便很多。

如果使用佔位符號則必須人為在傳引數中加%

List<User> list =userMapper.selectUserByName("%管理員%");

如果使用${}原始符號則不用人為在引數中加%,直接在mapper配置檔案裡面接受這個引數就可以了,顯得更加的方便,可是sql注入問題?  

List<User>list = userMapper.selectUserByName("管理員");

再比如order by排序,如果將列名通過引數傳入sql,根據傳的列名進行排序,應該寫為:

  1. ORDER BY ${columnName}  

這樣要執行的sql是:

  1. ORDER BY columnName  

如果使用#{}將無法實現此功能,因為如果這樣的話,執行的sql就變成了
  1. ORDER BY "columnName"