Mapper對映檔案中的#{}與${}
#{}實現的是向prepareStatement中的預處理語句中設定引數值,sql語句中#{}表示一個佔位符即?。
- <!--根據id查詢使用者資訊 -->
- <select id="findUserById"parameterType="int"resultType="user">
- select * from user where id =#{id}
- </select>
使用佔位符#{}可以有效防止sql注入,在使用時不需要關心引數值的型別,mybatis會自動進行Java型別和jdbc型別的轉換。#{}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。說得再通俗一點,當我們使用#{}的時候,發出的sql中,#{}代表的內容會自動被加上“”,而${}是直接把東西取出來直接用舉個例子:
id="liweizhong",#{id}輸出後是"liweizhong",而${value}輸出是liweizhong
${}和#{}不同,通過${}可以將parameterType傳入的內容拼接在sql中且不進行jdbc型別轉換, ${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。使用${}不能防止sql注入,但是有時用${}會非常方便,如下的例子:
- <!--根據名稱模糊查詢使用者資訊 -->
-
<select id="selectUserByName"parameterType="string"resultType="user">
- select * from user whereusername like '%${value}%'
- </select>
如果本例子使用#{}則傳入的字串中必須有%號,而%是人為拼接在引數中,顯然有點麻煩,如果採用${}在sql中拼接為%的方式則在呼叫mapper介面傳遞引數就方便很多。
如果使用佔位符號則必須人為在傳引數中加%
List<User> list =userMapper.selectUserByName("%管理員%");
如果使用${}原始符號則不用人為在引數中加%,直接在mapper配置檔案裡面接受這個引數就可以了,顯得更加的方便,可是sql注入問題?
List<User>list = userMapper.selectUserByName("管理員");
再比如order by排序,如果將列名通過引數傳入sql,根據傳的列名進行排序,應該寫為:
- ORDER BY ${columnName}
這樣要執行的sql是:
- ORDER BY columnName
如果使用#{}將無法實現此功能,因為如果這樣的話,執行的sql就變成了
- ORDER BY "columnName"