Именованные запросы JPA против API критериев?
-
27-10-2019 - |
Вопрос
Существует ли эвристический / рекомендательный подход / набор правил для выбора между Criteria API и NamedQuery ?
Мои мысли на данный момент:
Именованные запросы обычно более читабельны.Критерии запросов более гибкие.
Оба предварительно скомпилированы.Я предпочитаю как можно дольше использовать именованные запросы, а затем переходить к критериям.
Но может быть
стремление «согнуть» запрос с помощью API критериев является намеком на неоптимальный дизайн (т.е. разделение проблем)?
Спасибо
Решение
Именованные запросы более оптимальны (они анализируются / подготавливаются один раз).Запросы критериев являются динамическими (они не компилируются предварительно, хотя некоторые поставщики JPA, такие как EclipseLink, поддерживают кеш подготовки критериев).
Я бы использовал критерии только для динамических запросов.
Другие советы
Критерийные запросы - хороший выбор, когда запрос должен генерироваться динамически, например, на основе переменных и нескольких критериев поиска.
Для статических запросов JPQL гораздо удобнее для чтения, и я предпочитаю использовать их, чем запросы с критериями.Вы можете немного потерять безопасность, но модульные тесты должны сделать вас более уверенным.
Другая точка зрения состоит в том, что, хотя запрос критериев не так удобен для чтения, он безопасен для типов, поэтому обеспечивает проверку типов во время компиляции.Если вы изменяете базу данных в проектах, где много сущностей и много запросов, действительно полезно увидеть во время компиляции, какие запросы пошли не так из-за изменения.
С другой стороны, я не уверен, что это более выгодно, чем простота JPQL
На самом деле я просмотрел источник Hibernate (4.3.0-SNAPSHOT) и источник EclipseLink (2.5.0-SNAPSHOT) и просмотрел реализацию JPA в каждом из них.
Очевидно, что EclipseLink не является потокобезопасным в том виде, который вы описываете.В частности, он пытается многократно пересчитывать объединения.
Для меня реализация Hibernate выглядит поточно-ориентированной.Я не уверен на 100%, но похоже, что это так.Я бы сказал, что это не гарантируется в будущем, поскольку это не указано.
Однако предупреждаю, не думаю, что вы многого добьетесь.Насколько я понимаю, большая часть компиляции запроса фактически выполняется на этапе createQuery, так что вы даже не получите большого кеширования результатов.
JPA также предоставляет способ построения статических запросов в виде именованных запросов с использованием аннотаций @NamedQuery и @NamedQueries.В JPA считается хорошей практикой по возможности предпочитать именованные запросы динамическим запросам.Из http://www.objectdb.com/java/jpa/query/api