JOOQ: повторное использование/копирование запросов

Чтобы избежать повторного создания одной и той же части динамического запроса снова и снова, я собирался построить основную часть один раз, а затем повторно использовать эту часть в разных частях приложения. Поскольку построение запроса в некоторой степени связано (см. вопрос jOOQ: лучший способ получить поля с псевдонимами (из #as(alias, aliasFunction)) для одного из аспектов, почему это так), это должно повысить производительность...

К сожалению, мне пришлось понять, что различные «шаги» в шаблоне компоновщика не возвращают измененные копии, а изменяют базовое состояние. Таким образом, я искал способ создать неизменяемую копию определенного «шага» (например, SelectWhereStep), из которого можно инициализировать и впоследствии изменять (Select-) запрос каждый раз, когда он мне нужен. К сожалению, мне не удалось определить какой-либо («законный») способ добиться этого.

Можно ли это сделать? Если нет, то какая лучшая альтернатива?

"это должно улучшить производительность..." какие характеристики производительности вас особенно беспокоят? По сравнению с генерацией строки SQL построение дерева выражений совершенно незначительно во всех тестах. Аналогичным образом, по сравнению с выполнением инструкции SQL, все операции jOOQ в большинстве случаев весьма незначительны.
Lukas Eder 17.03.2019 14:32

@LukasEder Я понимаю, что это, вероятно, окажет незначительное влияние на производительность, запуская один и тот же код несколько раз (зная, что это даст один и тот же результат), это просто кажется неправильным. Я уже делаю, как вы предлагаете, выделяя общую часть конструкции запроса в отдельную функцию. Для меня было бы лучше, если бы был способ клонировать существующий запрос. Как вы думаете, вы могли бы добавить что-то подобное (или принять PR, который делает)?

Chris 17.03.2019 20:27
"это просто неправильно" - Да, мы это прекрасно знаем. "Как вы думаете, вы могли бы добавить что-то подобное" — Да, jOOQ 4.0 решит эту проблему. "или принять PR, который делает" - Нет, это совсем не простое изменение, которое хотелось бы получить в качестве пиара :)
Lukas Eder 18.03.2019 11:02
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
7
3
908
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Unfortunately, I've had to realize that the different "steps" in the builder pattern don't return amended copies, but modify underlying state

Это действительно очень неудачное ограничение в текущей конструкции jOOQ DSL / API моделей. API DSL должен должен быть неизменным, тогда как API модели является изменяемым. Но это не всегда так, как вы заметили.

В настоящее время нет способа клонировать запрос jOOQ, поскольку в большинстве случаев в этом нет необходимости. Независимо от того, работаете ли вы с изменяемым или неизменяемым API, самый простой способ добиться того, что вы хотите сделать, — составить запросы jOOQ функциональным образом. т.е. вместо

I was going to build the main part once and then reuse this part in different parts of the application

Вы можете просто сделать то же самое функциональным способом, а не императивным. Вместо того, чтобы назначать "основная часть" какой-либо локальной или глобальной переменной, вы можете создать функцию theMainPart(), которая возвращает эту часть на лету. Подробнее об этом в этом блоге.

В качестве примечания: при написании динамического SQL обычно есть лучшие способы, чем прямое обращение к типам XYZStep..

Безопасно ли использовать следующий пример в отношении того, что результат DSL.trunc используется дважды? Field<...> nowAsMonth = DSL.trunc(DSL.now(), DatePart.MONTH);Field<...> startAt = nowAsMonth.sub(...);Field<...> endAt = nowAsMonth.sub(...); Глядя на код, все кажется безопасным, потому что всегда создается новый Expression. Но откуда мне знать, не глядя на код? Потому что DSL.trunc возвращает то, что вы называете выражением/функцией столбца в ваших связанных документах?

Thorsten Schöning 30.01.2020 17:45

@ThorstenSchöning: Начиная с jOOQ 3.x, если вы хотите быть на 100% уверены, вы никогда не сможете повторно использовать какое-либо выражение. В худшем случае у вас есть экземпляр Param в дереве выражений, и кто-то вызывает устаревшее Param::setValue. Если вы прагматичны, то можете предположить, что выражение Field достаточно неизменно.

Lukas Eder 03.02.2020 13:09

Другие вопросы по теме