2017-04-26 218 views
0

我有一個使用用戶輸入的詞條查詢數據庫的搜索頁面。我在Spring中使用Mybatis 3.4.0。如何:帶單引號的Mybatis查詢詞/撇號

問題是Mybatis在搜索詞中刪除了任何單引號,無論我是否轉義它們。這些是有效的查詢,因爲用戶需要能夠搜索像O'Toole這樣的字符串,但是沒有任何內容被返回。

這是來自mapper的代碼片段。在考慮中的字段是caseWhereConditionDTO.value和傳入的值是,例如,O''TOOLE(手動代碼之前逸出)

<if test="caseWhereConditionDTO.value != null"> 
    ${caseWhereConditionDTO.leftExpression} 
    ${caseWhereConditionDTO.operator} 
    #{caseWhereConditionDTO.value} 
    ${caseWhereConditionDTO.closeConditionString} 
</if> 

這導致where子句

where UPPER(p.last_name ||', ' || p.first_name) LIKE 'OTOOLE%' 

其缺少雙轉義Ò 'TOOLE

一切工作正常,當在映射器中我用$替換#並用單引號括起來

'${caseWhereConditionDTO.value}' 

導致

where UPPER(p.last_name ||', ' || p.first_name) LIKE 'O''TOOLE%' 

一個SQL輸出這給預期的查詢結果

但我當然想保留#{}

這樣的SQL注入保護我問題是,如何使用單引號查詢條款,同時仍然使用#{}/prepared語句的sql注入保護?

+0

如果您已經使用雙引號手動轉義caseWhereConditionDTO.value,您是否可以使用文本字面值語法?例如,查看http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#sthref344,並工作以生成where子句,如where q'[UPPER(p.last_name || ',','|| p.first_name)like'O'TOOLE%']' –

回答

0

有2個選項,其中沒有必要逃避單引號:

  • 除非可以肯定的是輸入將不包含他們必須首先躲過任何%(如果他們輸入存在,並且是不會轉義,這會造成SQL的混淆:是%輸入的一部分或「運算符」?),然後將%連接到值:value = value + "%";,然後LIKE #{value}

  • 更好的選擇只是連接SQL查詢中的%LIKE #{value} || '%'。它確實有用,我剛剛重新檢查過它。

+0

我不確定我是否遵循,問題不在於''''''''''''被剝離出來 –

+0

已編輯答案:引號不需要轉義,而'%'可以。 – blackwizard

+0

我現在看到,是的,我在我的映射程序片段中單獨連接了%,即'$ {caseWhereConditionDTO.closeConditionString}'是%。你可以更詳細地瞭解不需要轉義的報價嗎? mybatis去掉引號是否我逃過他們 –