1、mybatis的官網關於$和#的字符串替換符號區別描述如下:
http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#Parameters
上面的意思是說:假如參數columnName的值是ID,那么${columnName}會變成ID,#{columnName}會被替換成'ID',變成了字符串,注意引號。
2、對於上面的描述談下自己的理解:
假如你使用符號#,那么輸入的參數會被看做字符串,假如你輸入參數ID,最后就會變成字符串'ID';
假如上面的的參數ID表示數據表的列名,你想根據這一列進行排序,你所期望的sql語句大概是這樣:select * from tb_name order by ID,可是,你使用#符號,在xxxMapper.xml中寫成下列模式:
1 <select id="queryByParams" parameterType="MyTestDO" resultMap="MyTestMap"> 2 SELECT * FROM tb_name order by #{ID} 3 </select>
最終生成的sql語句其實是這個樣子:select * from tb_name order by 'ID',這樣就無法實現根據列名ID進行排序的目的,因為沒有列名'ID',只有列名ID,但是sql語法沒有問題,可以執行。
對於這種情況,為了防止sql注入問題,我們只能限制傳入的參數內容或者形式,不能讓任意的參數內容傳入進來。比如下面的代碼:
1 String orderByType=request.getParameter(ORDER_BY_TYPE); 2 if(StringUtils.isNotEmpty(orderByType)){ 3 if(orderByType.equals("desc")||orderByType.equals("asc")){ 4 sqlParamFromRequest(sqlParams, ORDER_BY_TYPE); 5 } 6 } 7 8 String orderparam=request.getParameter("orderParam"); 9 if(StringUtils.isNotEmpty(orderparam)) { 10 11 if (orderparam.equals("normal_counting+abnormal_counting")) { 12 sqlParams.put("orderParam", "addnew"); 13 14 } else if(orderparam.equals("normal_counting")||orderparam.equals("abnormal_counting")||orderparam.equals("emulator_counting")||orderparam.equals("app_channel")){ 15 16 sqlParamFromRequest(sqlParams, ORDER_BY_PARME); 17 } 18 }
3、有些資料說like不能使用#符號,我實際測試,是可以用的
對於下面需要使用拼接的情況,是可以使用#符號的,像下面寫的這樣:
1 <select id="queryByParams" parameterType="MyTestDO" resultMap="MyTestMap"> 2 SELECT * FROM tb_shen 3 WHERE 1=1 4 <if test="name !=null">AND name LIKE CONCAT('%',#{name},'%')</if> 5 </select>
實際測試情況如下:(和上面的例子sql不符,因為這是后面修改的)
但是如果你寫成下面的樣子,在mybatis預處理的時候,是有問題的
1 <select id="queryByParams" parameterType="MyTestDO" resultMap="MyTestMap"> 2 SELECT * FROM tb_shen 3 WHERE 1=1 4 <if test="name !=null">AND name LIKE CONCAT('%','#{name}','%')</if> 5 </select>