Hibernate-caching
休止状態-キャッシュ
キャッシングは、システムのパフォーマンスを向上させるメカニズムです。 これは、アプリケーションとデータベースの間にあるバッファメモリです。 キャッシュメモリは、データベースのヒット数を可能な限り減らすために、最近使用したデータ項目を保存します。
キャッシングはHibernateにとっても重要です。 以下で説明するように、マルチレベルキャッシングスキームを利用します-
一次キャッシュ
1次キャッシュはセッションキャッシュであり、すべての要求が通過する必要がある必須キャッシュです。 Sessionオブジェクトは、データベースにコミットする前にオブジェクトを独自の力で保持します。
オブジェクトに対して複数の更新を発行する場合、Hibernateは更新の実行を可能な限り遅らせて、発行される更新SQLステートメントの数を減らします。 セッションを閉じると、キャッシュされているすべてのオブジェクトが失われ、データベースで永続化または更新されます。
二次キャッシュ
2次キャッシュはオプションのキャッシュであり、1次キャッシュは、2次キャッシュ内のオブジェクトの検索を試みる前に常に参照されます。 2次キャッシュは、クラスごとおよびコレクションごとに構成でき、主にセッション全体のオブジェクトのキャッシュを担当します。
Hibernateでは、サードパーティのキャッシュを使用できます。 org.hibernate.cache.CacheProvider インターフェースが提供されます。これは、Hibernateにキャッシュ実装へのハンドルを提供するために実装する必要があります。
クエリレベルキャッシュ
Hibernateは、2次キャッシュと密接に統合するクエリ結果セットのキャッシュも実装します。
これはオプションの機能であり、キャッシュされたクエリ結果とテーブルが最後に更新されたときのタイムスタンプを保持する2つの追加の物理キャッシュ領域が必要です。 これは、同じパラメーターで頻繁に実行されるクエリにのみ役立ちます。
二次キャッシュ
Hibernateはデフォルトで一次キャッシュを使用しますが、一次キャッシュを使用しても何もする必要はありません。 オプションの2次キャッシュに直接進みましょう。 すべてのクラスがキャッシュの恩恵を受けるわけではないため、2次キャッシュを無効にできることが重要です。
Hibernate 2次キャッシュは2つのステップでセットアップされます。 最初に、使用する同時方式を決定する必要があります。 その後、キャッシュプロバイダーを使用して、キャッシュの有効期限と物理キャッシュ属性を構成します。
並行性戦略
並行性戦略はメディエーターであり、データ項目をキャッシュに保存し、キャッシュからそれらを取得します。 2次キャッシュを有効にする場合は、永続クラスとコレクションごとに、使用するキャッシュ同時方式を決定する必要があります。
トランザクション-更新のまれなケースで、同時トランザクションで古いデータを防ぐことが重要である場合、ほとんどのデータに対してこの戦略を使用します。
読み取り/書き込み-更新のまれなケースで、同時トランザクションで古いデータを防止することが重要である場合、読み取り方式のデータに対して再びこの戦略を使用します。
Nonstrict-read-write -この戦略は、キャッシュとデータベース間の一貫性を保証しません。 データがほとんど変化せず、古いデータのわずかな可能性が重大な関心事ではない場合、この戦略を使用します。
読み取り専用-データに適した並行性戦略であり、変更されることはありません。 参照データのみに使用します。
*Employee* クラスに第2レベルのキャッシングを使用する場合、読み書き戦略を使用してEmployeeインスタンスをキャッシュするようHibernateに指示するために必要なマッピング要素を追加しましょう。
<?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. | Cache Name & Description |
---|---|
1 |
EHCache メモリまたはディスクおよびクラスターキャッシュにキャッシュでき、オプションのHibernateクエリ結果キャッシュをサポートします。 |
2 |
OSCache 有効な一連の有効期限ポリシーとクエリキャッシュのサポートにより、単一のJVMのメモリとディスクへのキャッシュをサポートします。 |
3 |
warmCache JGroupsに基づくクラスターキャッシュ。 クラスター化された無効化を使用しますが、Hibernateクエリキャッシュはサポートしません。 |
4 |
JBoss Cache JGroupsマルチキャストライブラリにも基づいた、完全にトランザクション化されたクラスター化キャッシュ。 レプリケーションまたは無効化、同期または非同期通信、および楽観的および悲観的ロックをサポートします。 Hibernateクエリキャッシュがサポートされています。 |
すべてのキャッシュプロバイダーは、すべての同時方式と互換性があるわけではありません。 次の互換性マトリックスは、適切な組み合わせの選択に役立ちます。
Strategy/Provider | Read-only | Nonstrictread-write | Read-write | Transactional |
---|---|---|---|---|
EHCache | X | X | X | |
OSCache | X | X | X | |
SwarmCache | X | X | ||
JBoss Cache | X | X |
hibernate.cfg.xml構成ファイルでキャッシュプロバイダーを指定します。 EHCacheを2次キャッシュプロバイダーとして選択します-
<?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にある必要があります。 Employeeクラスのehcache.xmlのキャッシュ構成は次のようになります-
<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"
/>
これで、2番目のレベルのキャッシュがEmployeeクラスとHibernateで有効になり、Employeeに移動するとき、または識別子でEmployeeを読み込むたびに2番目のレベルのキャッシュにヒットするようになりました。
すべてのクラスを分析し、クラスごとに適切なキャッシュ戦略を選択する必要があります。 場合によっては、第2レベルのキャッシュにより、アプリケーションのパフォーマンスが低下する可能性があります。 そのため、まずキャッシュを有効にせずにアプリケーションをベンチマークし、後で適切なキャッシュを有効にしてパフォーマンスを確認することをお勧めします。 キャッシュによってシステムのパフォーマンスが改善されない場合は、どのタイプのキャッシュを有効にしても意味がありません。
クエリレベルキャッシュ
クエリキャッシュを使用するには、最初に設定ファイルの hibernate.cache.use_query_cache = "true" プロパティを使用してアクティブ化する必要があります。 このプロパティをtrueに設定することにより、Hibernateが必要なキャッシュをメモリに作成し、クエリと識別子のセットを保持します。
次に、クエリキャッシュを使用するには、QueryクラスのsetCacheable(Boolean)メソッドを使用します。 たとえば-
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に指示します。