3

例如,给定一个文本框名称,用户需求希望能够进行通配符搜索(例如包含、开始于、结束于)。

只要我仍在后端(Java)中使用参数化查询,是否可以接受 sql 通配符('%' 和 '_')作为输入?有效地,允许用户构建自己的正则表达式,这就是用户的需求。

例子:

  1. 用户类型在

    textbox = '%are%'
    
  2. 该参数被馈送到后端,如下所示:

    public class PersonDaoImpl {
    
            public List<Person> search(String name){//name gets the value from textbox w/ sql wildcards
            Query q = mgr.createNativeQuery('select * from Person where name like :name'); //default to always use like since expecting searchkey with sql wildcards    
            q.setParameter('name', name);//gives the input from the screen
            return q.getResultList();
            } 
    }  
    
  3. 由于用户提供了正则表达式,结果集将包括名称为“Waren”、“Jared”、“Clare”、“Blare”的人。

使用 SQL 参数化查询,我可以确保我不会允许 SQL 注入。这实现了用户对通配符搜索的要求,但它是否违反了我可能遗漏的任何内容?

更新:刚刚从他们的帮助页面发现谷歌也允许通配符。

4

3 回答 3

3

好吧,它违反了用户需要知道(或被告知)如何构造 SQL“LIKE”语法的事实,但仅此而已。您可能会以这种方式最终得到一个缓慢的查询,因为它通常无法使用索引,但我不会担心安全性或正确性。

于 2011-10-14T06:19:51.203 回答
2

它是“安全的”,但可能不是一个好主意,原因有两个:

  1. 要求您的用户为此了解 sql 语法可能不是最好的 ui 设计。
  2. 性能很糟糕:这些查询通常无法使用您的索引,因此执行速度很慢。而且它们需要大量的 CPU 时间来比较所有文本,因此它们会为您的服务器增加大量负载(与已经很长的执行时间不成比例)。您需要一个依赖全文索引的解决方案。
于 2011-10-14T06:25:47.530 回答
0

我很好奇,name参数最终是如何在请求中设置的?这是什么平台?(之前错过了OP setParameter

正如您所指出的,用户需要知道通配符语法,即 , 等的使用%_更流行的方法是从用户名中获取字符串,以及“完全匹配”/“starts-with”的选项/'名字中的任何地方'。如果你走这条路,你还可以在前两种情况下执行更有效的查询。

编辑:

如果客户坚持contains查询,那么我认为您当前要求最终用户输入模式的方法比通过放置将输入字符串转换为模式更好%

这是因为用户仍然可以选择添加(或有选择地添加)%搜索字符串,从而加快查询执行速度。例如:

  • 如果用户输入搜索字符串Don,则查询为select ... from ... where name like 'Don'. RDBMS 很可能会使用 name 上的索引。

  • 如果用户输入搜索字符串Don%,则查询为select ... from ... where name like 'Don%'. RDBMS 仍然很可能使用 name 上的索引。

  • 如果用户输入搜索字符串%Don%Don%则索引无法使用。

于 2011-10-14T06:26:28.173 回答