Pull to refresh

Comments 39

А чем родной JPA с его JPQL (Java Persistence Query Language) не угодил?
Мне бы хотелось, чтобы синтаксис проверялся прямо при написании запроса в IDE. Хоть IDEA это и делает для стандартных SQL запросов вся остальная возня с JDBC мне неудобна. Я не пользуюсь в данном проекте стандартной объектной моделью. Практически ни один запрос не выбирает из базы всю строку целиком, берутся только необходимые поля. Кстати, Jooq мне показался гораздо более кратким, чем JPSQL. JPSQL большой и сложный. И медленный, мне кажется. Запрос ведь сначала надо распарсить.
UFO just landed and posted this here
Я бы сказал, что это аналог более отдаленный, чем те, что уже упомянуты. Тогда ведь придется сказать, что Hibernate HSQL тоже вроде как аналог, хотя это не совсем так. Считаете, стоит их добавить в статью? Мне казалось, это продукты разного класса и назначения. JPA в большой степени ORM, а Jooq — вообще не ORM, несмотря на поддержку ActiveRecord.
UFO just landed and posted this here
Я согласен, что, может быть, аналог, но уж точно не самый прямой. Обновлю статью чуть позже.
UFO just landed and posted this here
Я в общем-то недавно занялся Java. И тоже могу ошибаться. Но основное отличие Jooq в том, что это не ORM, он не требует наличия сущностей или POJO объектов. Это просто удобный низкоуровневый механизм исполнения произвольных SQL запросов, как SELECT, так и INSERT/UPDATE. JPA — это часть ORM, фактически, как я понимаю. Она работает с сущностями, а не с физическими данными базы. Насколько мне известно, ORM обычно не любят частично загруженные из базы объекты, поскольку это создает трудности с обеспечением корректной работы с полями, которые изначально загружены не были.

С Jooq (или с чистым SQL) я могу построить и выполнить запрос любой сложности и вложенности. Зная, что я пишу непосредственный SQL я могу его выстроить так, как будет оптимально для данной БД или для данного конкретного случая. C ORM я ограничен его правилами. C jooq я получаю только данные, которые мне нужны, с ORM я получаю объекты, как правило.

Просто у LINQ-подобных систем и у ORM систем несколько разные задачи. В настоящий момент я занимаюсь проектом, где серверу практически не нужно загружать/сохранять объекты целиком. Он не имеет пользовательского интерфейса и только обрабатывает информацию в базе данных некоторым сложным образом. Конечно, я бы мог к нему ORM прикрутить, но, думаю, что это перебор.

Jooq гораздо проще писать, чем такие запросы и уж тем более такие.
UFO just landed and posted this here
А каким образом тогда обеспечивается «типобезопасность»?

Да, вы правы. Jooq действительно генерирует классы для таблиц и полей. Они используются в основном только для генерации запросов. И у него есть разные методы возврата результатов. Я пользуюсь fetch() который возвращает Result — нетипизированный (этот объект почти настолько же сущность, насколько ResultSet в JDBC) или fetchAny/ fetch(Field). Типизированный Record можно получить только от SelectFrom(), который в DSL недоступен.

Данные отображаются в объекты, поэтому до них не так далеко. И как правило, поле в объекте — это поле в базе.

Да, согласен. Но разница все же есть. Разница в подходах. Jooq делает упор на SQL. Сущности вторичны и необязательны. А ORM-системы ставят сущности на первый план. В принципе, если бы это было не так, они бы не назывались ORM :)

Это есть в JPA Criteria API

Да, очень похоже. Но все же JPA синтаксис ужасен. Да и выглядит это неродным, на мой взгляд. Как будто разработано было просто для обеспечения дополнительного функционала, а не как логическое продолжение архитектуры системы. Слишком велики затрачиваемые усилия.
Заинтересовался библиотекой только сейчас, поэтому прочитал этот диалог только что. Возможно, ответ уже неактуален сторонам, но «who cares?».
Мне кажется, JOOQ — это следующая итерация на пути работы с базами. ORM удобен только в самом начале и только в простых случаях. Если хочешь работать с объектами — работай с объектными базами. Если работаешь с RDBMS, рано или поздно тебе захочется убрать прослойку из ORM. Просто ORM — это наиболее распространённый способ стартовать с минимумом потерь времени на работу с db в самом начале.
Согласен, но JOOQ еще нужно немного вырасти для того, чтобы стать ORM следующего поколения. Все же удобство сериализации объектов в нем пока ниже чем то, что есть в хороших ORM.
Если имеете в виду отсуствие reference'ов на другие классы (подгрузка графов объектов), то это просто следствие того, что эта либа — не ORM. В принципе, я уже пришел к тому, что неудобства работы с таким графом в виде кэшей и неконтролируемого SQL больше, чем пользы.
Да, согласен. Во многих случаях использование ORM утяжеляет проект.
Эх, при всем уважении к статье (хорошо написана, с примерами), хотелось бы отметить что «LINQ» это гараздо больше, чем просто «построитель запросов к бд».

Лично я считаю, что основная «фича» LINQ — это то, как он использует Expressions для анализа того, что реально стоит сделать. Что «q.Where( x => x>5 )» на самом деле может превратится не только в DB-запрос, но и запрос к гуглу… или ваабще может быть просто как хинт к провайдеру что ему нужно сделать.

Кроме того, его можно использовать очень много где — тот же PLINQ уже совсем не имеет отношения к работе с базой данных. Или eactive Extensions for (Rx).

Надеюсь в Java тоже скоро станет возможным делать подобные штуки.
Именно поэтому LINQ в заголовке взято в кавычки :)
Ну это хорошее Слово Для Привлечения Внимания :)

На самом деле с LINQ и правда ничего общего, LINQ — это прежде всего провайдер, построенный на Expression Trees.

Здесь же скорее «Fluent-синтаксис для формирования запросов к БД». Если мне (в .NET) нужен именно SQL, без лишнего уровня абстракции (например, чтобы писать очень точные оптимизированные запросы), я бы сделал это так же как в Jooq, и без использования LINQ.
Да, я согласен, конечно. LINQ стал настолько известен, что еще пара лет и это слово станет нарицательным, как ксерокс :)
А я сколько искал, не мог найти подобное чудо почему-то. Видать, плохо искал. Автору — тысячу нефти.
from c in SomeCollection
where c.SomeProperty < someValue * 2
select new {c.SomeProperty, c.OtherProperty};


Вот это LINQ, а то что у вас то просто флуент АПД для постоения запросов к БД.
Миша, ну LINQ, справедливости ради — это тоже только во вторую очередь такая вот конструкция с ключевыми словами. А в первую — это провайдер и такой же набор Fluent-Extension-методов к нему.

Я лично, кстати, предпочитаю писать именно так:
someCollection
.Where(c => c.SomeProperty < someValue * 2)
.Select(c => new { c.SomeProperty, c.OtherProperty });
Language Integrated Query — Интегрированные в язык запросы. ИМХО то что мой пример разворачивается в ваш, это просто деталь реализации. И фишка далеко не в реализации.
Не совсем уловил мысль про «деталь реализации» и «фишка далеко не в реализации». Можно уточнить?

«Интегрированные в язык запросы» — верно, но я смотрю на «интегрированные» не как на синтаксическую конструкцию, а именно как на «возможность формировать запросы на языке (C#) напрямую, а не на каком-то другом (внешнем) языке, например, SQL», и тут уже неважно как это выглядит синтаксически — главное, что есть C#, выражения, преимущество строгой типизации (когда нужно) и, соответственно, compile-time-check.
Сам подход (и Jooq и аналоги) — что он дает? Только compile-time checking?
Зачем писать тот же SQL, только не на SQL? Я бы назвал это «обфусцированный SQL».
> Только compile-time checking?

А этого мало? Даже в покрытом тестами коде, всегда остаётся вероятность что-то упустить из виду.
Дополнительная проверка никогда не повредит.
И уж лучше узнать об ошибке на этапе сборки, нежели от разъярённого клиента.
Это немало, само по себе. Только для этого не обязательно коверкать SQL синтаксис в нечто нечитабельное. Можно ведь взять SQL и скормить базе, она все проверит. В крайнем случае парсеру данного диалекта.

Но этого одного IMHO мало, чтобы перевесить все недостатки такого подхода.
Смысл не в разовой проверке. Потом этот сиквел поддерживать надо.
Пока запросов немного, ещё вполне возможно как-то с этим управляться, и глазками проверять и копипастить в клиент DB.
Но как только их количество, а главное и количество мест, откуда эти к этим запросам идут вызовы, переваливает некий порог, то простое переименование колонки может обернуться головной болью, даже если рефакторинг идёт в продвинутой IDE.
Я, заметьте, не говорил о разовой проверке. разумеется проверку нужно делать при каждой компиляции (или изменении запроса). Мы сравниваем способ хранения SQL кода внутри Java кода (или другого языка) — в текстовом или вот в таком виде.

Поддерживать сиквел нужно в любом случае. Разве такое представление запроса избавит от необходимости проверять глазками и копипастить в клиент БД? Ведь нужно не просто проверить синтаксис, а еще убедиться, что запрос
  • выполнится без ошибок
  • вернет правильный результат
  • выполнится с приемлемой производительностью
Сейчас сделать это, не покидая IDE возможности нет, (а должна быть наверное), значит нужно копипастить туда-сюда. Как это делать с данным представлением?

простое переименование колонки может обернуться головной болью
Верно. Как эта проблема решается в больших серьезных проектах? За запросы отвечают специиально обученные DB-разработчики, для которых родной язык — SQL. Как им работать с таким представлением? В статье приведены довольно примитивные примеры, а в реальных проектах запросы на 20+ строк и 5+ таблиц — обычное дело.
UFO just landed and posted this here
Для динамического SQL, как указано в статье, будет использоваться другой синтаксис (a=new Query(); a.addSelect(); a.addFrom()), верно? Тут я согласен, что он удобнее, чем StringBuilder. Как построитель динамических запросов, Jooq найдет себе применение.
UFO just landed and posted this here
На Scala такой DSL бы смотрелся красивее :)
Вот если бы тот же LambdaJ стал бы частью языка… хотя, пожалуй, так и появилась Scala :)
Sign up to leave a comment.

Articles