Это правильный способ разрешить поиск по шаблону для пользователя? - PullRequest
3 голосов
/ 14 октября 2011

Например, учитывая имя текстового поля, пользовательское требование хочет иметь возможность поиска по шаблону (например, содержит, начинается с, заканчивается на).

Можно ли принимать в качестве входных данных символы подстановки sql ('%' и '_'), если я все еще использую параметризованный запрос в серверной части (Java)?Фактически, позволяя пользователю создавать свое собственное регулярное выражение, в чем и состоит его требование.

Пример:

  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. Набор результатов будет включать людей с именами «Варен», «Джаред», «Клэр», «Блэр», как и ожидалось, поскольку пользователь предоставил регулярное выражение.

С помощью запроса параметризации SQL я могу гарантировать, что не позволю SQL-инъекцию.Это реализует требование пользователя для поиска по шаблону, но, возможно, нарушает ли я что-то, что я, возможно, пропустил?

ОБНОВЛЕНИЯ: Только что на странице справки было обнаружено, что Google также позволяет использовать символы подстановки.1025 *

Ответы [ 3 ]

3 голосов
/ 14 октября 2011

Ну, это нарушает тот факт, что пользователь должен знать (или ему нужно сказать), как создать синтаксис SQL "LIKE", но это все. Таким образом, вы можете получить медленный запрос, поскольку он обычно не может использовать индекс, но меня не будут беспокоить вопросы безопасности или правильности.

2 голосов
/ 14 октября 2011

Это "безопасно", но, вероятно, не очень хорошая идея по двум причинам:

  1. Вероятно, это не лучший дизайн пользовательского интерфейса, требующий от пользователей знать синтаксис sql для этого.
  2. Это ужасно для производительности: эти запросы часто не могут использовать ваши индексы, поэтому они выполняются медленно. И им требуется много времени процессора для сравнения всего этого текста, поэтому они добавляют большую нагрузку (непропорционально к уже высокому времени выполнения) на ваш сервер. Вам нужно решение, основанное на полнотекстовом индексе.
0 голосов
/ 14 октября 2011

Мне любопытно, как параметр name получает значение в запросе? Что это за платформа? (ОП пропустил setParameter ранее)

Как вы заметили, пользователь должен знать синтаксис подстановочного знака, то есть использовать %, _ и т. Д. Более популярный подход - просто получить строку из имени пользователя вместе с опцией для ' точное совпадение '/' начинается с '/' везде-в-имени '. Если вы пойдете по этому пути, вы также сможете выполнить более эффективный запрос в первых двух случаях.

EDIT:

Если клиент настаивает на запросе contains, то я думаю, что ваш текущий подход заключается в том, чтобы потребовать от конечного пользователя более точного ввода шаблона, чем преобразовывать строку ввода в шаблон, поместив вокруг него %.

Это потому, что пользователи по-прежнему будут иметь возможность , а не , добавляя (или выборочно добавляя) % к строке поиска, что приводит к более быстрому выполнению запроса. Например:

  • Если пользователь вводит строку поиска Don, запрос select ... from ... where name like 'Don'. СУБД, скорее всего, будет использовать индекс по имени.

  • Если пользователь введет строку поиска Don%, запрос будет select ... from ... where name like 'Don%'. СУБД все еще вполне вероятно будет использовать индекс по имени.

  • Если пользователь вводит строку поиска %Don или %Don%, индекс не может быть использован.

...