Учебники

Hibernate — Кэширование

Кэширование — это механизм повышения производительности системы. Это буферная память, которая лежит между приложением и базой данных. Кэш-память хранит недавно использованные элементы данных, чтобы максимально уменьшить количество обращений к базе данных.

Кеширование также важно для Hibernate. Он использует многоуровневую схему кэширования, как описано ниже —

Hibernate Кэширование

Кэш первого уровня

Кэш первого уровня — это кэш сеанса, который является обязательным кешем, через который должны проходить все запросы. Объект Session держит объект в своих собственных полномочиях, прежде чем зафиксировать его в базе данных.

Если вы выпускаете несколько обновлений для объекта, Hibernate пытается отложить выполнение обновления как можно дольше, чтобы уменьшить количество выпущенных операторов SQL обновления. Если вы закроете сеанс, все кэшируемые объекты будут потеряны и сохранены или обновлены в базе данных.

Кэш второго уровня

Кэш второго уровня — это необязательный кеш, и к нему всегда обращаются, прежде чем предпринимать какие-либо попытки найти объект в кеше второго уровня. Кэш второго уровня может быть настроен для каждого класса и коллекции и в основном отвечает за кэширование объектов между сеансами.

Любой сторонний кеш может быть использован с Hibernate. Предоставляется интерфейс org.hibernate.cache.CacheProvider , который должен быть реализован, чтобы обеспечить Hibernate дескриптором реализации кэша.

Кэш на уровне запросов

Hibernate также реализует кеш для наборов результатов запросов, который тесно интегрируется с кешем второго уровня.

Это необязательная функция, для которой требуются две дополнительные области физического кэша, в которых хранятся результаты кэшированного запроса и отметки времени последнего обновления таблицы. Это полезно только для запросов, которые часто выполняются с одинаковыми параметрами.

Кэш второго уровня

Hibernate по умолчанию использует кэш первого уровня, и вам нечего делать, чтобы использовать кэш первого уровня. Давайте перейдем прямо к дополнительному кешу второго уровня. Не все классы получают выгоду от кэширования, поэтому важно иметь возможность отключить кэш второго уровня.

Кэш второго уровня Hibernate настраивается в два этапа. Сначала вы должны решить, какую стратегию параллелизма использовать. После этого вы настраиваете срок действия и физические атрибуты кеша с помощью провайдера кеша.

Стратегии параллелизма

Стратегия параллелизма — это посредник, который отвечает за хранение элементов данных в кэше и извлечение их из кэша. Если вы собираетесь включить кэш второго уровня, вам придется решить, для каждого постоянного класса и коллекции, какую стратегию параллельного использования кэша использовать.

  • Транзакционный. Используйте эту стратегию для данных, предназначенных главным образом для чтения, где важно предотвратить устаревшие данные в параллельных транзакциях в редких случаях обновления.

  • Чтение-запись — снова используйте эту стратегию для данных, предназначенных главным образом для чтения, где важно предотвратить устаревшие данные в параллельных транзакциях, в редких случаях обновления.

  • Nonstrict-read-write — эта стратегия не гарантирует согласованности между кешем и базой данных. Используйте эту стратегию, если данные почти никогда не изменяются и небольшая вероятность устаревших данных не является критической проблемой.

  • Только для чтения — стратегия параллелизма, подходящая для данных, которая никогда не изменяется. Используйте его только для справочных данных.

Транзакционный. Используйте эту стратегию для данных, предназначенных главным образом для чтения, где важно предотвратить устаревшие данные в параллельных транзакциях в редких случаях обновления.

Чтение-запись — снова используйте эту стратегию для данных, предназначенных главным образом для чтения, где важно предотвратить устаревшие данные в параллельных транзакциях, в редких случаях обновления.

Nonstrict-read-write — эта стратегия не гарантирует согласованности между кешем и базой данных. Используйте эту стратегию, если данные почти никогда не изменяются и небольшая вероятность устаревших данных не является критической проблемой.

Только для чтения — стратегия параллелизма, подходящая для данных, которая никогда не изменяется. Используйте его только для справочных данных.

Если мы собираемся использовать кэширование второго уровня для нашего класса Employee , добавим элемент отображения, необходимый для того, чтобы Hibernate кэшировал экземпляры Employee, используя стратегию чтения-записи.

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <cache usage = "read-write"/>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Атрибут use = «read-write» указывает Hibernate использовать стратегию параллельного чтения и записи для определенного кэша.

Поставщик кэша

Следующим шагом после рассмотрения стратегий параллелизма станет использование классов-кандидатов в кэш для выбора поставщика кеша. Hibernate заставляет вас выбирать одного поставщика кеша для всего приложения.

Sr.No. Имя и описание кэша
1

EHCache

Он может кэшироваться в памяти или на диске, а также в кластерном кэшировании и поддерживает дополнительный кэш результатов запроса Hibernate.

2

OSCache

Поддерживает кэширование в память и на диск в одной JVM с богатым набором политик истечения срока действия и поддержкой кэша запросов.

3

warmCache

Кластерный кеш на основе JGroups. Он использует кластеризованную аннулирование, но не поддерживает кэш запросов Hibernate.

4

JBoss Cache

Полностью транзакционный реплицируемый кластерный кеш, также основанный на многоадресной библиотеке JGroups. Он поддерживает репликацию или аннулирование, синхронную или асинхронную связь, а также оптимистическую и пессимистическую блокировки. Кеш запросов Hibernate поддерживается.

EHCache

Он может кэшироваться в памяти или на диске, а также в кластерном кэшировании и поддерживает дополнительный кэш результатов запроса Hibernate.

OSCache

Поддерживает кэширование в память и на диск в одной JVM с богатым набором политик истечения срока действия и поддержкой кэша запросов.

warmCache

Кластерный кеш на основе JGroups. Он использует кластеризованную аннулирование, но не поддерживает кэш запросов Hibernate.

JBoss Cache

Полностью транзакционный реплицируемый кластерный кеш, также основанный на многоадресной библиотеке JGroups. Он поддерживает репликацию или аннулирование, синхронную или асинхронную связь, а также оптимистическую и пессимистическую блокировки. Кеш запросов Hibernate поддерживается.

Каждый поставщик кэша не совместим с любой стратегией параллелизма. Следующая матрица совместимости поможет вам выбрать подходящую комбинацию.

Стратегия / Provider Только для чтения Nonstrictread-записи Читай пиши транзакционный
EHCache Икс Икс Икс
OSCache Икс Икс Икс
SwarmCache Икс Икс
JBoss Cache Икс Икс

Вы будете указывать поставщика кеша в файле конфигурации hibernate.cfg.xml. Мы выбираем EHCache в качестве нашего поставщика кэша второго уровня —

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
   
      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
   
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   
   </session-factory>
</hibernate-configuration>

Теперь вам нужно указать свойства областей кэша. EHCache имеет свой собственный файл конфигурации, ehcache.xml , который должен находиться в CLASSPATH приложения. Конфигурация кэша в ehcache.xml для класса Employee может выглядеть так:

<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"
maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>

Вот и все, теперь у нас включено кэширование второго уровня для класса Employee, а Hibernate теперь обращается к кэшу второго уровня, когда вы переходите к Employee или когда вы загружаете Employee по идентификатору.

Вы должны проанализировать все свои классы и выбрать подходящую стратегию кэширования для каждого из классов. Иногда кэширование второго уровня может снизить производительность приложения. Поэтому рекомендуется сначала провести сравнительный анализ вашего приложения, не включая кэширование, а затем включите хорошо подходящее кэширование и проверьте производительность. Если кэширование не улучшает производительность системы, то нет смысла включать любой тип кэширования.

Кэш на уровне запросов

Чтобы использовать кэш запросов, сначала необходимо активировать его, используя свойство hibernate.cache.use_query_cache = «true» в файле конфигурации. Установив для этого свойства значение true, вы заставляете Hibernate создавать необходимые кеши в памяти для хранения наборов запросов и идентификаторов.

Далее, чтобы использовать кеш запросов, вы используете метод setCacheable (Boolean) класса Query. Например —

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate также поддерживает очень тонкую поддержку кэша благодаря концепции области кэша. Регион кеша является частью кеша, которому дано имя.

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

Этот код использует метод, чтобы сообщить Hibernate хранить и искать запрос в области кэша сотрудников.