Встроенный SQL в ОО-языках, таких как Java - PullRequest
7 голосов
/ 08 января 2010

Одна из вещей, которая раздражает меня при работе с SQL на языках OO, - это необходимость определять операторы SQL в строках.

Когда я работал на мейнфреймах IBM, языки использовали препроцессор SQL для синтаксического анализа операторов SQL из собственного кода, поэтому операторы могли быть записаны в открытом тексте SQL без запутывания строк, например, в Cobol есть EXEC SQL .... END-EXEC синтаксическая конструкция, которая позволяет операторам чистого SQL быть встроенными в коде Cobol.

<pure cobol code, including assignment of value
 to local variable HOSTVARIABLE>    

EXEC SQL
       SELECT COL_A, COL_B, COL_C
       INTO :COLA, :COLB, :COLC
       FROM TAB_A
       WHERE COL_D = :HOSTVARIABLE
END_EXEC

<more cobol code, variables COLA, COLB, COLC have been set>

... это делает оператор SQL действительно простым для чтения и проверки на наличие ошибок. Между токенами EXEC SQL .... END-EXEC нет ограничений на отступы, разрывы строк и т. Д., Поэтому вы можете форматировать оператор SQL по своему вкусу.

Обратите внимание, что этот пример предназначен для выбора из одной строки, когда ожидается набор результатов из нескольких строк, кодировка отличается (но все еще v. Легко читается).

Итак, на примере Java

  1. Что сделало нежелательным подход «старый КОБОЛ» ? При таком подходе не только SQL, но и системные вызовы могут быть намного более читабельными. Давайте назовем это встроенным препроцессором иностранного языка .

  2. Было бы полезно реализовать встроенный препроцессор иностранного языка для SQL? Видите ли вы выгоду в том, что сможете писать нативные операторы SQL внутри Java-кода?

Редактировать

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

Ответы [ 7 ]

4 голосов
/ 08 января 2010

Уже существует стандарт для встроенного SQL в Java, он называется SQLJ .

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

2 голосов
/ 08 января 2010

Уже существует нечто похожее на «встроенный языковой препроцессор» для Java и .NET в домене SQL: http://ibatis.apache.org/

Кроме того, люди обычно используют полноценный ORM, такой как Hibernate , для абстрагирования SQL.

Обратите внимание, что эти инструменты не позволяют хранить строки SQL в самом коде Java, но служат аналогичным целям. Лично я не вижу никакой пользы в хранении строк SQL в самом коде, так как это обычно более грязно. Аккуратно записанный весь SQL-код в конкретном файле помогает повторно использовать и поддерживать ваш SQL. Они допускают использование SQL в качестве строк, если в этом возникает необходимость, но обычно это является последним средством (когда инструмент ORM не имеет хорошей абстракции для вашего варианта использования.)

РЕДАКТИРОВАТЬ: я думаю, смешивание SQL и кода (будь то ОО или нет) хрупко и не желательно. Намного лучше иметь централизованное место для хранения ваших запросов. Это подход iBATIS.

1 голос
/ 17 января 2010

Вы можете обойти такую ​​неспособность с приличной IDE. Например, IntelliJ IDEA поддерживает функции, которые называются внедренными языками. Это позволяет вам писать код на желаемом языке внутри строкового литерала и иметь возможность использовать подсветку кода, завершение, навигацию и другие сервисы. Подробнее об этом вы можете прочитать здесь: http://blogs.jetbrains.com/idea/2009/03/user-defined-language-injection/

1 голос
/ 08 января 2010

Для текущего положения дел я могу предложить следующие пункты

  • Как уже упоминалось выше, в Java есть метод, который делает это: SQLJ , который никогда не занимал.
  • Обычно каждый использует ORM, чтобы получить похожий результат ( iBatis и Hibernate - это те, о которых я больше всего здесь говорю
  • C # имеет LINQ, который делает что-то похожее

Существует много проблем с встраиванием sql как части языка:

  • Он имеет тенденцию связывать ваш язык с поставщиком базы данных, поскольку различные SQL-диалекты очень разные.Это не годится для большинства современных языков. Это не было проблемой для COBOL, поскольку переносимость не была обязательной.
  • Это делает либо язык более сложным, либо требует предварительной обработки, оба являются плохими вещами сами по себе.Да, но с современными IDE это еще хуже, так как им будет трудно обрабатывать sql внутри своего кода (хотя они начинают фактически делать это, даже когда sql встраиваетсядед в строках).Это не было проблемой для COBOL, так как в современном смысле это все-таки уродливый язык (хотя, вероятно, было приятно, когда он был изобретен)
  • Требуются ресурсы для компиляции, которые трудно контролировать (именуемобазы данных) и следовать совершенно другому подходу, чем «нормальное» программирование.Опять же, программа на COBOL и ее база данных в значительной степени слиты воедино, поэтому никаких проблем нет.
  • SQL не подходит для OO Paradigm.Он возвращает двумерные массивы значений, а не объектов.Так что вам все равно нужен какой-то ORM.

С другой стороны, DSL - это теперь все шумиха.И есть языки, которые имеют литералы XML.Поэтому я думаю, что вполне возможно, что появляются языки (или уже существуют), которые имеют встроенные в них возможности, подобные ORM, и позволяют вам использовать SQL (или HQL?), Например, DSL, внутри кода.

1 голос
/ 08 января 2010

Объектно-реляционные инструменты отображения, такие как Hibernate, теоретически делают подобные вещи менее проблемными."теоретически";)

Кроме того, если вы можете использовать Grails, я слышал, что вы можете просто написать фантастические многострочные строки, которые облегчают чтение операторов SQL.

0 голосов
/ 05 апреля 2014

Одним из основных недостатков такого подхода, как SQLJ , является тот факт, что препроцессоры будут препятствовать использованию современных инструментов IDE для вашей логики доступа к данным. С такими превосходными IDE, как Eclipse , NetBeans или IntelliJ IDEA , это сильный аргумент против препроцессоров ( мы также писали об этом в нашем блоге ).

В то же время, такие инструменты DSL, как Eclipse Xtext или JetBrains MPS , все еще пытаются улучшить язык Java как таковой, чтобы иметь что-то, что вы привыкли иметь в COBOL.

Один из вариантов - использовать для работы внутренний DSL, такой как jOOQ , хотя на самом деле это не SQL

0 голосов
/ 08 января 2010

Что ж, самый простой, самый умопомрачительный способ сделать это - просто включить ваш SQL в виде строки в ваш код.

Что-то вроде

   Statement s = new Statement("Select * from wherever");

Это может быть не очень сложно, но это работает. Недостатком является то, что компилятор не может проверить ваш синтаксис SQL. Немного лучшим решением является Подготовленные операторы , где вы указываете параметрический шаблон. Таким образом, вы можете делать такие вещи, как:

PreparedStatement s = connection.prepareStatement("Select * from wherever where state = ?");

Таким образом, ваше соединение JDBC должно вызвать исключение, как только вы создадите подготовленный оператор во время выполнения. Так что, если код работает с первого раза, он должен работать всегда.

Затем в вашем коде позже, когда вы захотите изменить параметр, который вы делаете:

s.setString(1, "CA");

У Microsoft есть встроенный язык запросов для .net, который называется LINQ . Для баз данных вы используете LINQ to SQL , что позволяет встраивать запросы прямо в ваш код.

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