Гибернация - Кеширование
Кэширование - это механизм повышения производительности системы. Это буферная память, которая находится между приложением и базой данных. Кэш-память хранит недавно использованные элементы данных, чтобы максимально уменьшить количество обращений к базе данных.
Кеширование также важно для Hibernate. Он использует многоуровневую схему кэширования, как описано ниже -
Кэш первого уровня
Кэш первого уровня - это кеш сеанса, который является обязательным кешем, через который должны проходить все запросы. Объект Session сохраняет объект под своей властью перед фиксацией его в базе данных.
Если вы выпускаете несколько обновлений для объекта, Hibernate пытается отложить выполнение обновления как можно дольше, чтобы уменьшить количество выдаваемых SQL-операторов обновления. Если вы закроете сеанс, все кэшируемые объекты будут потеряны и либо сохранятся, либо обновятся в базе данных.
Кэш второго уровня
Кэш второго уровня является необязательным кешем, и кеш первого уровня всегда будет запрашиваться перед любой попыткой найти объект в кэше второго уровня. Кэш второго уровня может быть настроен для каждого класса и для каждой коллекции и в основном отвечает за кэширование объектов между сеансами.
Любой сторонний кеш можно использовать с Hibernate. Anorg.hibernate.cache.CacheProvider предоставляется интерфейс, который должен быть реализован, чтобы предоставить Hibernate дескриптор реализации кеша.
Кэш на уровне запроса
Hibernate также реализует кеш для наборов результатов запросов, который тесно интегрируется с кешем второго уровня.
Это дополнительная функция, для которой требуются две дополнительные области физического кэша, в которых хранятся кэшированные результаты запроса и отметки времени, когда таблица была обновлена в последний раз. Это полезно только для запросов, которые часто выполняются с одними и теми же параметрами.
Кэш второго уровня
Hibernate по умолчанию использует кеш первого уровня, и вам нечего делать, чтобы использовать кеш первого уровня. Перейдем сразу к необязательному кешу второго уровня. Не все классы выигрывают от кэширования, поэтому важно иметь возможность отключить кеш второго уровня.
Кэш второго уровня Hibernate настраивается в два этапа. Во-первых, вы должны решить, какую стратегию параллелизма использовать. После этого вы настраиваете истечение срока действия кеша и атрибуты физического кеша с помощью поставщика кеша.
Стратегии параллелизма
Стратегия параллелизма - это посредник, который отвечает за хранение элементов данных в кеше и извлечение их из кеша. Если вы собираетесь включить кэш второго уровня, вам нужно будет решить для каждого постоянного класса и коллекции, какую стратегию параллелизма кеширования использовать.
Transactional - Используйте эту стратегию для данных, в основном для чтения, когда критически важно предотвратить устаревание данных в параллельных транзакциях, в редких случаях обновления.
Read-write - Снова используйте эту стратегию для данных, в основном для чтения, когда критически важно предотвратить устаревание данных в параллельных транзакциях, в редких случаях обновления.
Nonstrict-read-write- Эта стратегия не гарантирует согласованности между кешем и базой данных. Используйте эту стратегию, если данные почти никогда не меняются и небольшая вероятность устаревших данных не является критической проблемой.
Read-only- Стратегия параллелизма, подходящая для данных, которые никогда не меняются. Используйте его только для справочных данных.
Если мы собираемся использовать кеширование второго уровня для наших Employee class, давайте добавим элемент сопоставления, необходимый для указания 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>
Атрибут usage = "read-write" указывает Hibernate использовать стратегию параллелизма чтения-записи для определенного кеша.
Провайдер кеша
Ваш следующий шаг после рассмотрения стратегий параллелизма, вы будете использовать классы кандидатов в кэш, чтобы выбрать поставщика кеша. Hibernate заставляет вас выбрать одного поставщика кеша для всего приложения.
Sr. No. | Имя и описание кеша |
---|---|
1 |
EHCache Он может кэшировать в памяти или на диске и кластеризованное кеширование, а также поддерживает дополнительный кеш результатов запросов Hibernate. |
2 |
OSCache Поддерживает кэширование в память и на диск в одной JVM с богатым набором политик истечения срока действия и поддержкой кеширования запросов. |
3 |
warmCache Кластерный кеш на основе JGroups. Он использует кластерную недействительность, но не поддерживает кеш запросов Hibernate. |
4 |
JBoss Cache Кластерный кеш с полной репликацией транзакций также основан на многоадресной библиотеке JGroups. Он поддерживает репликацию или аннулирование, синхронную или асинхронную связь, а также оптимистичную и пессимистическую блокировку. Кэш запросов Hibernate поддерживается. |
Не каждый поставщик кеша совместим со всеми стратегиями параллелизма. Следующая матрица совместимости поможет вам выбрать подходящую комбинацию.
Стратегия / Провайдер | Только чтение | Нестрогое чтение-запись | Читай пиши | Транзакционный |
---|---|---|---|---|
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, который должен быть в КЛАССЕ приложения. Конфигурация кеша в 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 теперь попадает в кеш второго уровня всякий раз, когда вы переходите к сотруднику или когда вы загружаете сотрудника по идентификатору.
Вам следует проанализировать все свои классы и выбрать подходящую стратегию кеширования для каждого из классов. Иногда кэширование второго уровня может снизить производительность приложения. Поэтому рекомендуется сначала протестировать ваше приложение, не включая кеширование, а затем включить подходящее кеширование и проверить производительность. Если кеширование не улучшает производительность системы, нет смысла включать какой-либо тип кэширования.
Кэш на уровне запроса
Чтобы использовать кеш запросов, вы должны сначала активировать его с помощью 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, что нужно сохранять и искать запрос в области сотрудников кеша.