Вот полезный метод для этого конкретного случая, когда у вас есть несколько предложений в вашем WHERE
, но вы не знаете заранее, какие из них вам нужно применить.
Будет ли ваш пользователь искать по названию?
select id, title, author from book where title = :title
Или по автору?
select id, title, author from book where author = :author
Или оба?
select id, title, author from book where title = :title and author = :author
Достаточно плохо только с 2 полями. Количество комбинаций (и, следовательно, различных PreparedStatements) растет экспоненциально с количеством условий. Верно, скорее всего, у вас достаточно места в пуле PreparedStatement для всех этих комбинаций, и для программного построения предложений в Java вам просто нужна одна ветвь if
для каждого условия. Все равно не так красиво.
Вы можете аккуратно исправить это, просто составив SELECT
, который будет выглядеть одинаково независимо от того, требуется ли каждое отдельное условие.
Вряд ли мне нужно упоминать, что вы используете PreparedStatement
, как было предложено в других ответах, и NamedParameterJdbcTemplate подойдет, если вы используете Spring.
Вот:
select id, title, author
from book
where coalesce(:title, title) = title
and coalesce(:author, author) = author
Затем вы указываете NULL
для каждого неиспользуемого условия. coalesce()
— это функция, которая возвращает свой первый ненулевой аргумент. Таким образом, если вы передадите NULL
вместо :title
, первое предложение будет where coalesce(NULL, title) = title
, которое оценивается как where title = title
, которое, будучи всегда истинным, не влияет на результаты.
В зависимости от того, как оптимизатор обрабатывает такие запросы, производительность может снизиться. Но, вероятно, не в современной базе данных.
(Хотя эта проблема и похожа, она не аналогична проблеме с предложением IN (?, ?, ?)
, когда вы не знаете количество значений в списке, так как здесь у вас знает фиксированное количество возможных пунктов, и вам просто нужно активировать/деактивировать их по отдельности.)
person
Andrew Spencer
schedule
22.12.2015
PreparedStatement
. - person T.J. Crowder   schedule 12.11.2010insert
илиselect
: используйтеPreparedStatement
для всех пользовательских значений. Ваша проблема на самом деле не отличается от других, за исключением того, что вам нужно создать SQL для оператора (и отдельно параметры), но суть одна и та же. - person T.J. Crowder   schedule 12.11.2010