Здесь можно рассмотреть несколько оптимизаций.
- HTTP-сессия
- Кэш второго уровня
- Использование
@NamedQuery
, где это возможно - Не используйте первичные ключи на основе строк.
Кэш HTTP-сессии
Вы всегда можете сохранить объект, который вы выбираете с помощью метода #findOne
, в сеансе HTTP, когда клиентпроверяет подлинность и значение не существует.Это исключит запросы на все последующие аутентифицированные запросы.Единственное беспокойство, которое вы должны предпринять, - если рассматриваемый объект был изменен текущим пользователем, вы захотите заменить значение в сеансе обновленной копией.
Многие веб-приложения используют этот механизм.Если вы когда-либо входили в свою кредитную карту или в систему банковских счетов в Интернете и вызывали их, чтобы что-то изменить, вы, вероятно, заметили, что вы должны выйти из системы и снова войти в нее, чтобы эти изменения были видны.Это та же концепция.
Кэш второго уровня
Это решение прекрасно работает даже для приложений, не основанных на HTTP, которые используют Hibernate.В этом случае у вас есть хранилище данных на стороне приложения, которое вы конфигурируете для хранения результатов запроса для редко изменяемой информации.Вместо того чтобы относить стоимость базы данных и сети по каждому запросу к чему-либо, существующему в кеше, Hibernate сначала будет гидрировать из кеша, если записи еще не истекли.
Хорошая вещь в 2LC в том, что вы можетенастройте для каждого запроса, если он будет кэшироваться, и вы также можете настроить различные таймауты и другие параметры конфигурации для каждого типа объекта.
@ NamedQuery
Иногда выполнение сложных запросов выполняется за счетJPQL / HQL повторяется.Если вы обнаружите, что это является проблемой, вы можете посмотреть, можно ли вместо этого переместить запрос в статический @NamedQuery
.
Преимущество @NamedQuery
заключается в том, что синтаксический анализ, проверка и построение базового дерева синтаксического анализа выполняются один раз во время повышения уровня приложения.Это означает, что во время выполнения Hibernate просто выбирает это определение, получает предварительно сгенерированный SQL, применяет привязки параметров и передает их в базу данных.За исключением проверки типа параметра, накладные расходы очень минимальны.
Нет ключей на основе строк
В зависимости от вашей платформы базы данных первичные ключи на основе строк могут работать намного хуже, чем их числовые счетчики, особенноесли ваш запрос участвует в объединениях.Если ваше строковое поле сконфигурировано для поддержки юникода (например, столбцы NVARCHAR или NCHAR), вы усугубляете проблему.
Использование String для @NaturalId
прекрасно, потому что вы обычно просто применяетегде предикат против того поля, в котором вы можете применять различные индексы в соответствии с вашими запросами.
Но я бы посоветовал, если в вашем запросе используется первичный ключ на основе строк, переместите его на @NaturalId
и используйте суррогатный числовой ключ для первичного ключа.Вы заметите, что ваши объединения таблиц значительно улучшат производительность, так как сравнение и поиск хеша между ними намного быстрее.