Hibernate-キャッシング

キャッシングは、システムのパフォーマンスを向上させるメカニズムです。これは、アプリケーションとデータベースの間にあるバッファメモリです。キャッシュメモリは、データベースヒットの数を可能な限り減らすために、最近使用されたデータ項目を格納します。

キャッシングはHibernateにとっても重要です。以下に説明するように、マルチレベルのキャッシュスキームを利用します。

第1レベルのキャッシュ

第1レベルのキャッシュはセッションキャッシュであり、すべてのリクエストが通過する必要のある必須のキャッシュです。Sessionオブジェクトは、データベースにコミットする前に、オブジェクトを独自の権限で保持します。

オブジェクトに複数の更新を発行する場合、Hibernateは、発行される更新SQLステートメントの数を減らすために、更新の実行を可能な限り遅らせようとします。セッションを閉じると、キャッシュされているすべてのオブジェクトが失われ、データベースで永続化または更新されます。

第2レベルのキャッシュ

第2レベルのキャッシュはオプションのキャッシュであり、第2レベルのキャッシュでオブジェクトを見つけようとする前に、常に第1レベルのキャッシュが参照されます。第2レベルのキャッシュは、クラスごとおよびコレクションごとに構成でき、主にセッション間でオブジェクトをキャッシュします。

サードパーティのキャッシュはすべてHibernateで使用できます。アンorg.hibernate.cache.CacheProvider Hibernateにキャッシュ実装へのハンドルを提供するために実装する必要があるインターフェースが提供されます。

クエリレベルのキャッシュ

Hibernateは、第2レベルのキャッシュと緊密に統合されたクエリ結果セットのキャッシュも実装します。

これはオプションの機能であり、キャッシュされたクエリ結果とテーブルが最後に更新されたときのタイムスタンプを保持する2つの追加の物理キャッシュ領域が必要です。これは、同じパラメーターで頻繁に実行されるクエリにのみ役立ちます。

第2レベルのキャッシュ

Hibernateはデフォルトで第1レベルのキャッシュを使用し、第1レベルのキャッシュを使用するために何もする必要はありません。オプションの第2レベルのキャッシュに直接移動しましょう。すべてのクラスがキャッシュの恩恵を受けるわけではないため、第2レベルのキャッシュを無効にできることが重要です。

Hibernateの第2レベルのキャッシュは2つのステップでセットアップされます。まず、使用する同時実行戦略を決定する必要があります。その後、キャッシュプロバイダーを使用して、キャッシュの有効期限と物理キャッシュ属性を構成します。

並行性戦略

同時実行戦略はメディエーターであり、データのアイテムをキャッシュに格納し、キャッシュから取得する役割を果たします。第2レベルのキャッシュを有効にする場合は、永続クラスとコレクションごとに、使用するキャッシュの同時実行戦略を決定する必要があります。

  • Transactional −この戦略は、まれに更新される場合に、同時トランザクションで古いデータを防止することが重要なほとんどのデータを読み取るために使用します。

  • Read-write −まれに更新が発生する場合に、同時トランザクションで古いデータを防止することが重要なデータのほとんどを読み取るために、この戦略を再度使用します。

  • Nonstrict-read-write−この戦略は、キャッシュとデータベース間の一貫性を保証するものではありません。データがほとんど変更されず、古いデータの可能性がほとんどない場合は、この戦略を使用してください。

  • Read-only−データに適した同時実行戦略。変更されることはありません。参照データとしてのみ使用してください。

に第2レベルのキャッシュを使用する場合 Employee クラスでは、読み取り/書き込み戦略を使用して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では、アプリケーション全体に対して単一のキャッシュプロバイダーを選択する必要があります。

シニア番号 キャッシュの名前と説明
1

EHCache

メモリまたはディスクとクラスター化されたキャッシュにキャッシュでき、オプションのHibernateクエリ結果キャッシュをサポートします。

2

OSCache

豊富な有効期限ポリシーとクエリキャッシュのサポートにより、単一のJVMでメモリとディスクへのキャッシュをサポートします。

3

warmCache

JGroupsに基づくクラスターキャッシュ。クラスター化された無効化を使用しますが、Hibernateクエリキャッシュをサポートしていません。

4

JBoss Cache

完全にトランザクションで複製されたクラスター化されたキャッシュも、JGroupsマルチキャストライブラリに基づいています。レプリケーションまたは無効化、同期または非同期通信、および楽観的および悲観的ロックをサポートします。Hibernateクエリキャッシュがサポートされています。

すべてのキャッシュプロバイダーは、すべての同時実行戦略と互換性があるわけではありません。次の互換性マトリックスは、適切な組み合わせを選択するのに役立ちます。

戦略/プロバイダー 読み取り専用 Nonstrictread-write 読み書き トランザクション
EHCache バツ バツ バツ  
OSCache バツ バツ バツ  
SwarmCache バツ バツ    
JBossキャッシュ バツ     バツ

hibernate.cfg.xml構成ファイルでキャッシュプロバイダーを指定します。第2レベルのキャッシュプロバイダーとして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に含まれている必要があります。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"
/>

これで、EmployeeクラスとHibernateに対して第2レベルのキャッシュが有効になり、従業員に移動するとき、または識別子で従業員を読​​み込むときに、第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に指示します。