Самый чистый способ построить строку SQL в Java - PullRequest
95 голосов
/ 16 декабря 2008

Я хочу создать строку SQL для выполнения манипуляций с базой данных (обновления, удаления, вставки, выбора и тому подобное) - вместо ужасного метода concat для строк, использующего миллионы "+" и кавычек, которые невозможно прочитать при лучше всего - должен быть лучший способ.

Я задумывался об использовании MessageFormat - но он должен использоваться для пользовательских сообщений, хотя я думаю, что он будет работать разумно - но я думаю, что должно быть что-то более согласованное с операциями типов SQL в библиотеках java sql.

Будет ли Groovy хорошим?

Ответы [ 14 ]

2 голосов
/ 27 апреля 2017

Чтение файла XML.

Вы можете прочитать его из файла XML. Его легко поддерживать и работать. Существуют стандартные парсеры STaX, DOM, SAX, которые позволяют сделать несколько строк кода в Java.

Больше с атрибутами

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

Maintaince

Вы можете поместить xml вне банки и легко поддерживать его. Те же преимущества, что и у файла свойств.

Преобразование

XML расширяемый и легко конвертируемый в другие форматы.

Вариант использования

Metamug использует XML для настройки файлов ресурсов REST с помощью sql.

2 голосов
/ 02 февраля 2009

Я работал над приложением 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 присутствует и установлено в значение "true", биты 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, и весь код принадлежит большой корпорации. Когда-нибудь я могу взять свои идеи и построить новую платформу с открытым исходным кодом, но я надеюсь, что один из существующих крупных игроков примет вызов.

1 голос
/ 16 декабря 2008

Если вы поместите строки SQL в файл свойств, а затем прочитаете их, вы можете сохранить строки SQL в текстовом файле.

Это не решает проблемы типа SQL, но, по крайней мере, значительно упрощает копирование и вставку из TOAD или sqlplus.

0 голосов
/ 16 декабря 2008

Как получить конкатенацию строк, кроме длинных строк SQL в PreparedStatements (которые вы можете легко предоставить в текстовом файле и в любом случае загрузить в качестве ресурса), которые разбиваются на несколько строк?

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

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