Динамическое создание предложения WHERE из пользовательских критериев поиска - PullRequest
5 голосов
/ 11 сентября 2009

У меня есть то, что, я уверен, является довольно распространенной проблемой, и я не хочу заново изобретать колесо. У меня есть форма поиска, где пользователи могут указать критерии поиска и тип поиска (И ИЛИ Ext.).

Форма передает идентификаторы, которые отображаются на имена и значения столбцов. В настоящее время я использую серверную Java для склеивания строк в предложение where. В некоторых случаях это работает, но неуклюже, подвержено ошибкам и плохо масштабируется.

Есть предложения?

Спасибо

David

Ответы [ 7 ]

1 голос
/ 11 сентября 2009

Я бы использовал подготовить и? для параметров в любом случае, если только для того, чтобы избежать инъекций и других рисков неправильного преобразования.

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

Если нет, вы можете динамически поддерживать пул подготовленных запросов. Это не так полезно для веб-приложения, где вам, вероятно, не удастся повторно использовать какие-либо запросы, которые вы готовите.

1 голос
/ 11 сентября 2009

Если вы используете ORM (я использую Hibernate), вы можете использовать Criteria API: он позволяет вам агрегировать условия (например, используя цикл) и создает результирующий запрос.

В нативном SQL я не знаю библиотеки, которая бы это делала. Может быть, вы могли бы написать свой собственный, черпая вдохновение из документации и кода для Hibernate Criteria?


OR

Если вы делаете что-то достаточно сложное на клиенте (скажем, вы управляете приоритетами между AND и OR, вы можете вкладывать условия, используя скобки ...), то вы, вероятно, уже создаете структуру данных , которая обрабатывает это на клиенте.

В этом случае я предлагаю вам отправить эту структуру данных на сервер и использовать ее через циклы для построения вашего запроса.

0 голосов
/ 11 сентября 2009

Книга Адама Мачаника "Экспертная разработка SQL Server 2005" содержит несколько замечательных предложений, касающихся динамического SQL. Он погружается во все виды проблем, включая производительность, ремонтопригодность и безопасность. Я не буду пытаться переписать его главу - достаточно сказать, что он считает, что чем меньше, тем больше, когда речь идет о SQL.

Это специфично для SQL Server, но я полагаю, что его общий подход (огромное условие where по сравнению с if / then SQL против динамического) может быть применен повсеместно.

РЕДАКТИРОВАТЬ: Я думаю, что стоит добавить ... никогда не доверяйте ввод от клиента, всегда параметризировать свой ввод перед использованием его в SQL.

0 голосов
/ 11 сентября 2009

Если вы используете Hibernate в качестве ORM, используйте API Criteria для этого. Должно быть проще добавлять / удалять пункты на основе некоторых условий.

Если вы создаете запрос jdbc, сначала сохраните постоянную часть и добавьте изменяющуюся часть, например, для

выберите * из транс где userid =?

и добавлять в зависимости от условий, например
если сумма! = ноль, тогда добавьте 'и количество>? '

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

0 голосов
/ 11 сентября 2009

Предложение Массимилиано Флири взглянуть на Criteria API заставило меня двигаться в правильном направлении. Я прекратил что-то о построении «просто условия where» и начал думать об этом как о необходимости строить утверждения.

Это привело меня к решению: Squiggle-sql: http://code.google.com/p/squiggle-sql/

Из документов:

Squiggle - небольшая библиотека Java для динамического создания операторов SQL SELECT. Это хорошее место для приложений, которые должны создавать сложные запросы с критериями, которые меняются во время выполнения. Обычно бывает довольно сложно понять, как построить эту строку. Squiggle снимает большую часть этой боли.

0 голосов
/ 11 сентября 2009

Hibernate имеет Criteria API, который позволяет создавать динамические запросы, используя только вызов метода, без необходимости ручного составления SQL-запроса.

Но вам следует рассмотреть возможность использования решения для полнотекстового поиска, такого как Lucene или Hibernate Search, которое значительно снижает потребность в запросах со сложным условием. Полнотекстовый поиск также является гораздо лучшим решением для удобства пользователей, поскольку полнотекстовый поиск проще и обычно дает лучшие результаты.

0 голосов
/ 11 сентября 2009

Вы должны построить строку поиска либо на клиенте, либо на сервере. Создание его на клиенте, очевидно, не является хорошим решением (с точки зрения безопасности), поэтому единственный вариант - создать его на сервере. Лично я бы использовал или построил объект Searcher, который обрабатывает повторяющуюся задачу эффективного построения строк поиска и создает из него Statement.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...