Кэш сущностей и запросов
Кэш сущностей
Кэш сущностей предоставляется фреймворком EclipseLink ORM. Он сохраняет недавно прочитанные или записанные экземпляры сущностей в памяти, что сводит к минимуму необходимость доступа к базе данных и повышает производительность приложения.
Кэш сущностей используется только при извлечении по ID, поэтому запросы по другим атрибутам по-прежнему выполняются к базе данных. Однако эти запросы могут быть проще и быстрее, если связанные сущности кэшированы. Например, если вы запрашиваете несколько заказов Orders вместе со связанными клиентами Customers и не используете кэш, SQL-запрос будет содержать JOIN для таблицы Customers. Если сущности Customer кэшированы, SQL-запрос выберет только Orders, и связанные Customers будут извлечены из кэша.
Чтобы включить кэширование для сущности, установите свойства приложения eclipselink.cache.shared.<entity_name>
и eclipselink.cache.size.<entity_name>
. В приведенном ниже примере для сущности User
установлен кэш с максимальным размером в 500 экземпляров:
eclipselink.cache.shared.User = true
eclipselink.cache.size.User = 500
По умолчанию имя сущности – простое имя класса. Но имя также можно задать явно в аннотации |
Размер кэша для сущности по умолчанию равен 100 экземплярам.
При использовании фетч-планов факт кэширования сущности влияет на режим извлечения, выбираемый фреймворком для загрузки ссылок. Если ссылочный атрибут является кэшируемой сущностью, режим извлечения всегда устанавливается в UNDEFINED
. Это позволяет ORM извлекать ссылку из кэша вместо выполнения запросов с JOIN или отдельных пакетных запросов.
При работе в распределенной конфигурации Jmix обеспечивает синхронизацию кэша сущностей между узлами кластера.
Кэш запросов
Кэш запросов хранит идентификаторы экземпляров сущностей, возвращаемых JPQL-запросами, поэтому он естественным образом дополняет кэш сущностей.
Например, если кэш включен для сущности (скажем, Customer
), и вы впервые выполняете запрос select c from Customer c where c.grade = :grade
, происходит следующее:
-
ORM запускает запрос к базе данных.
-
Загруженные экземпляры
Customer
помещаются в кэш сущностей. -
Сопоставление текста запроса и параметров со списком ID возвращаемых экземпляров помещается в кэш запросов.
При выполнении того же запроса с теми же параметрами во второй раз, фреймворк находит запрос в кэше запросов и загружает экземпляры сущностей из кэша сущностей по ID. С базой данных никаких операций не выполняется.
По умолчанию запросы не кэшируются. Указать, что запрос должен кэшироваться можно на разных уровнях приложения:
-
Используя XML-атрибут
cacheable = "true"
или методsetCacheable(true)
интерфейсаCollectionLoader
при работе с загрузчиками данных. -
Используя метод
cacheable(true)
интерфейса fluent loader при работе с DataManager. -
Используя аннотацию
@QueryHints(@QueryHint(name = PersistenceHints.CACHEABLE, value = "true"))
на методе репозитория при работе с репозиториями данных. -
Используя метод
setHint(PersistenceHints.CACHEABLE, true)
интерфейсаjakarta.persistence.Query
при работе сEntityManager
.
Используйте кэширование запросов только в том случае, если для возвращаемой сущности включен кэш сущностей. В противном случае при каждом запросе экземпляры сущностей будут извлекаться из базы данных по их ID один за другим. |
Кэш запросов автоматически инвалидируется, когда ORM создает, обновляет или удаляет экземпляры соответствующих сущностей. Инвалидация работает по всему кластеру.
Бин JMX jmix.eclipselink:type=QueryCache
можно использовать для мониторинга состояния кэша и удаления кэшированных запросов вручную. Например, если вы изменили экземпляр сущности Customer
непосредственно в БД, то необходимо удалить все кэшированные запросы для этой сущности, используя операцию evict()
, предоставляющую Customer
в качестве аргумента.
Если вы хотите отключить кэш запросов для всех сущностей независимо от вызовов API, описанных выше, установите для свойства приложения jmix.eclipselink.query-cache-enabled значение false
.