Я работал над приложением сервлета Java, которое должно создавать очень динамические операторы SQL для целей специальной отчетности. Основная функция приложения - передать кучу именованных параметров HTTP-запроса в предварительно закодированный запрос и создать красиво отформатированную таблицу вывода. Я использовал Spring MVC и структуру внедрения зависимостей для хранения всех моих SQL-запросов в файлах XML и загрузки их в приложение для создания отчетов вместе с информацией о форматировании таблиц. В конце концов, требования к отчетности стали более сложными, чем возможности существующих структур сопоставления параметров, и мне пришлось написать свои собственные. Это было интересное упражнение в разработке, и он позволил создать структуру для отображения параметров, гораздо более надежную, чем все, что я мог найти.
Новые сопоставления параметров выглядели так:
select app.name as "App",
${optional(" app.owner as "Owner", "):showOwner}
sv.name as "Server", sum(act.trans_ct) as "Trans"
from activity_records act, servers sv, applications app
where act.server_id = sv.id
and act.app_id = app.id
and sv.id = ${integer(0,50):serverId}
and app.id in ${integerList(50):appId}
group by app.name, ${optional(" app.owner, "):showOwner} sv.name
order by app.name, sv.name
Прелесть полученного фреймворка заключалась в том, что он мог обрабатывать параметры HTTP-запроса непосредственно в запросе с надлежащей проверкой типов и проверкой ограничений. Для проверки ввода не требуется дополнительных сопоставлений. В приведенном выше примере запроса параметр с именем serverId
будет проверен, чтобы убедиться, что он может быть приведен к целому числу и находится в диапазоне от 0 до 50. Параметр appId будет обрабатываться как массив целых чисел с максимальной длиной 50. Если поле showOwnerприсутствует и установлено значение «истина», биты SQL в кавычках будут добавлены к сгенерированному запросу для дополнительных сопоставлений полей. field Доступно еще несколько сопоставлений типов параметров, включая необязательные сегменты SQL с дополнительными сопоставлениями параметров. Он позволяет реализовать настолько сложное отображение запросов, насколько это может придумать разработчик. Он даже имеет элементы управления в конфигурации отчета, чтобы определить, будет ли данный запрос иметь окончательные сопоставления с помощью PreparedStatement или просто запускаться как предварительно созданный запрос.
Для примеров значений запроса Http:
showOwner: true
serverId: 20
appId: 1,2,3,5,7,11,13
Это даст следующий SQL:
select app.name as "App",
app.owner as "Owner",
sv.name as "Server", sum(act.trans_ct) as "Trans"
from activity_records act, servers sv, applications app
where act.server_id = sv.id
and act.app_id = app.id
and sv.id = 20
and app.id in (1,2,3,5,7,11,13)
group by app.name, app.owner, sv.name
order by app.name, sv.name
Я действительно думаю, что Spring или Hibernate или одна из этих структур должны предлагать более надежный механизм сопоставления, который проверяет типы, позволяет использовать сложные типы данных, такие как массивы и другие подобные функции. Я написал свой движок исключительно для своих целей, он не совсем читается для общего выпуска. На данный момент он работает только с запросами Oracle, а весь код принадлежит большой корпорации. Когда-нибудь я воспользуюсь своими идеями и построю новый фреймворк с открытым исходным кодом, но я надеюсь, что один из существующих крупных игроков примет вызов.