2017-04-26 63 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去掉引号是否我逃过他们 –