有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java这是允许用户进行通配符搜索的正确方法吗?

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

只要我还在后端(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注入。这实现了通配符搜索的用户需求,但它是否违反了我可能遗漏的任何内容

更新: 刚刚发现谷歌也允许通配符,从他们的help page


共 (3) 个答案

  1. # 1 楼答案

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

    1. 要求用户了解sql语法可能不是最好的ui设计
    2. 对于性能来说,这是非常糟糕的:这些查询通常不能使用索引,所以执行起来很慢。它们需要大量的cpu时间来比较所有这些文本,因此它们会给服务器增加大量负载(与已经很高的执行时间不成比例)。您需要一个依赖全文索引的解决方案
  2. # 2 楼答案

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

    正如您所指出的,用户需要知道通配符语法,即%_等的使用。一种更流行的方法是只从用户名中获取字符串,以及一个“精确匹配”/“以“/”名称中的任意位置开头”的选项。如果你走这条路,在前两种情况下,你也将能够执行更高效的查询

    编辑:

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

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

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

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

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

  3. # 3 楼答案

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