Такие структуры, как hibernate и JOOQ, создают SQL-запросы в строке на основе выбранного диалекта
Да.В jOOQ есть внутренний StringBuilder
, который собирает фрагменты SQL из вашего дерева выражений, которые генерируются специально для вашего целевого диалекта SQL.Вы можете увидеть, как это работает в действии на этом сайте: https://www.jooq.org/translate. Попробуйте перевести, например, этот ввод: SELECT * FROM t LIMIT 1
(который может соответствовать вашему использованию jOOQ API ctx.selectFrom(T).limit(1)
. Это переводит:
-- Oracle 12c and more
SELECT * FROM t FETCH NEXT 1 ROWS ONLY
-- Oracle 11g and less
SELECT *
FROM (
SELECT x.*, rownum rn
FROM (SELECT * FROM t) x
WHERE rownum <= 1
)
WHERE rn > 0
Если это так, какой самый оптимальный способ поддержать это в нашей собственной структуре?
Вам необходимо:
- Дерево выраженийпредставление вашего запроса SQL.
- При желании вы можете проанализировать строку для построения этого дерева выражений, например, синтаксический анализатор jOOQ , если вы хотите поддерживать фактический SQL, или вы можете иметь собственную языковую абстракциюкак Hibernate сделал с HQL / JPQL
- Обходите это дерево выражений, используя что-то вроде посетителя для сбора строк SQL и переменных связывания.
Но!
Несоздайте свой собственный, когда у вас есть готовые продукты, такие как jOOQ или, в некоторой степени, Hibernate, которые могут сделать то же самое. Создание такой обобщенной абстракции SQL действительно сложно, и если вы не хотите на самом делепродать такой продукт (вы, вероятно, не задали вопрос), тратить это время на создание этого продукта совсем не стоит.
Приведенная выше эмуляция LIMIT
является одним из более простых примеров из jOOQ., Вот еще кое-что, что поможет вам отказаться от прокрутки своего собственного , и этот ответ все еще просто поцарапает поверхность того, что jOOQ делает за кулисами.