Как стать автором
Обновить

Комментарии 27

Извиняюсь, а каким образом было выбрано название метода «setInsertRows», как это соответствует его назначению?
Вы абсолютно правы. К сожалению, мной была допущена глупая ошибка, в результате которой я называл методы setInsertRows() и setUpdateRows(), вместо положенных setInsertFields() и setUpdateFields(). Сейчас это недоразумение исправлено здесь, в коде и в Wiki, а я приношу Вам глубочайшие извинения
А вы рассматривали queryDSL? Для создания самой базы может и не пойдет, но вот писать запросы явно удобней
Этот проект остался мной незамеченным. Очень Вам благодарен — я обязательно его посмотрю

Никогда не понимал таких "фишек". Ейбогу, гораздо проще зайди в базу и написать и оттестить запрос на чистом SQL.

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

Я не против этого решения :)
Каждый работает так, как считает эффективным. Если кто-то всю сознательную жизнь работал на чистом SQL, то он и продолжит на нем работать. Новичку же, вероятно будет проще с текущим вариантом.


Хотя ему так и так придется изучать теорию и нормальные формы, чтобы уметь эффективно проектировать базы.

Спасибо за Ваше мнение :)

Обычно либо хватает простого SQL, либо, если уж хочется статической проверки, то полноценно подключается тот же упомянутый JOOQ. А тут довольно странный промежуточный шаг. Впрочем, на вкус и цвет...

Ввиду
Сгенерирует простейший:
SELECT * FROM `table1`

есть подозрение, что эта штука поддерживает только mysql.
Ваша правда. Я сознательно упустил этот момент в изложенном материале, так как понимаю, что такое ограничение не уместно и работаю сейчас над поддержкой PostgreSQL. Спасибо
Что будет если написать
"name %i"

где name VARCHAR(80)
запрос успешно выполнится, но в качестве значения для name Вы будете должны указать значение типа int
либо String, которое, однако, также будет приведено к типу int
А как обращаться к колонкам, которые имеют в названиях пробелы и спецсимволы:  "`My cRaZy %` $d"?
символ ` у меня не экранируется, поэтому нужно подождать, пока я это исправлю, а в остальном все должно работать как надо
Обычно обратные кавычки это и есть экранирование имен колонок.
Да, но дело в том, что они будут добавлены к имени этой колонки. В результате получится так, что обратная кавычка закроет добавленную конструктором открывющую
У SQL Builder в чём-то схожий подход.
new SelectBuilder()
    .column("name")
    .column("age")
    .from("Employee")
    .where("dept = 'engineering'")
    .where("salary > 100000")
    .toString();

Получается
select name, age from Employee where dept = 'engineering' and salary > 100000

А как там будет выглядеть:


select e.name, e.surname, b.summ from employe e, bills b where b.employeid=e.id and ((e.age>51 and b.type=2) or b.type=1);

Выбрать ФИО+суммы для всех, кто старше 51 года и получал платежи типа 2 или всех кто получил платеж типа 1.

Как-то так
new SelectBuilder()
    .column("e.name")
    .column("e.surname")
    .column("b.summ")
    .from("employe e, bills b")
    .where("b.employeid=e.id and ((e.age>51 and b.type=2) or b.type=1)")
    .toString();


Прелесть в том что можно строить запрос динамически, вот тут автор показывает как:

Спасибо! Я просто хотел для себя проветить теорию о том, что на сложных запросам будет таки больше SQL, и что (мое личное мнение) выигрышь получается лишь на простых запросах.

    .where("dept = 'engineering'")
    .where("salary > 100000")

Если я правильно понял, то в случае когда значение для dept или salary приходит от пользователя, то его нужно фильтровать вручную, иначе тут будет присутствовать SQL-инъекция.

В моем случае запись бы имела следующий вид:
.where("dept %s", IQL.EQUAL, "engineering")
.where("salary %i", IQL.MORE, 10000)

что привело бы к экранированию escape-последовательностей, а сигнатуры типов (%s и %i) здесь нужны именно для этого
Порядок команд не имеет значения, например GROUP BY можно указать после LIMIT, WHERE после ORDER BY, а JOIN перед SELECT

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


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

В целом jooq очень хорош и по мне разобраться с ним не так сложно.

А как будет выглядеть простой запрос на несколько сотен строк типа такого:
INSERT INTO NameYourTableResult (
		Field1,
		Field2,
		Field3 
		... 
		FieldN
	)
	WITH --в этот блок помещаются временные таблицы, которые и заменяют View
	TempTable1 as (
		--Сложный SQL запрос, результат которого будет храниться в TempTable1 на протяжении всего INSERT INTO
	)
	TempTable2 as (
		--Сложный SQL запрос, в котором мы можем использовать временную таблицу TempTable1 и другие таблицы базы данных
	)
	TempTable3 as (
		--Сложный SQL запрос, в котором мы можем использовать временные таблицы TempTable1, TempTable2 и другие таблицы базы данных
	)
	--... и так далее, но главное не увлекаться :)
	
	--Основной блок SELECT, из которого результаты пойдут в команду INSERT INTO (количество полей в SELECT равно количеству полей в INSERT)
	--В этом запросе SELECT используются временные таблицы TempTable1, TempTable2, TempTable3 и т.д. и другие источники данных
	SELECT --Перечень полей
	FROM TempTable3, sourceTable1, sourceTable2, sourceTable3
	JOIN ...
	WHERE ...;
Такого рода запросы должны писаться вручную в любом случае
Когда сталкивался с таким, разбивал на несколько простых запросов, а потом конкатенацией делал один общий.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории