永続性: オブジェクトはデータベース レコードとの対応関係を確立し、同期を維持します。オブジェクトは永続コンテキストにバインドされており、将来の状態変更やデータ変更はワークユニットの管理下にあります。これが永続状態です。 Session.load は Hibernate3.2 で提供されるデフォルトの遅延ロードメソッドで、ロードされるのはプロキシであり、永続的な状態とも言えます。
遅延ロード メカニズムは、不要なパフォーマンスのオーバーヘッドを回避するために提案されています。いわゆる遅延ロードとは、データが実際に必要なときにデータ ロード操作が実際に実行されることを意味します。遅延ロードを使用する場合、使用されるオブジェクトは、プロキシ オブジェクトのすべてのメンバー変数とメソッドを含むプロキシ オブジェクトです。ただし、このオブジェクトでは、メンバー変数の値は NULL であり、Hibernate は 1 組のエンティティを提供します。さらに、Hibernate3 はプロパティの遅延ロードも提供します。以下では、これらのタイプの遅延読み込みの詳細をそれぞれ紹介します。
A. エンティティ オブジェクトの遅延読み込み:
エンティティ オブジェクトに遅延読み込みを使用する場合は、以下に示すように、エンティティのマッピング構成ファイルで対応する構成を構成する必要があります。
<休止状態マッピング>
…
クラスの遅延属性を true に設定すると、エンティティの遅延読み込み機能をオンにできます。次のコードを実行すると:
ユーザー user=(ユーザー)session.load(ユーザー.クラス,”1”);(1)
System.out.println(user.getName()); (2)
(1) を実行する場合、Hibernate はデータのクエリを開始しません。一部のデバッグ ツール (JBuilder2005 のデバッグ ツールなど) を使用するか、デバッグ ブレークポイント監視を使用すると、この時点でユーザー オブジェクトのメモリ スナップショットが取得されます。この時点で返されるのが User$EnhancerByCGLIB$$bede8986 型のオブジェクトである可能性があり、その属性が null であることに驚くでしょう。 session.load() メソッドは、エンティティ オブジェクトのプロキシ クラス オブジェクトを返します。ここで返されるオブジェクト タイプは、User オブジェクトのプロキシ クラス オブジェクトです。 Hibernate では、CGLIB を使用してターゲット オブジェクトのプロキシ クラス オブジェクトを動的に構築します。プロキシ クラス オブジェクトにはターゲット オブジェクトのすべてのプロパティとメソッドが含まれており、すべてのプロパティには null が割り当てられます。デバッガによって表示されたメモリ スナップショットから、この時点で実際の User オブジェクトがプロキシ オブジェクト
の CGLIB$CALBACK_0.target 属性に含まれていることがわかります。
(2)までのコードが実行されると、user.getName()メソッドが呼び出されます。このとき、CGLIBが提供するコールバック機構を通じて、実際にはCGLIB$CALBACK_0.getName()メソッドが呼び出されます。 Hibernate はまず CGLIB$CALBACK_0.target 属性が null かどうかを確認し、null でない場合はターゲット オブジェクトの getName メソッドを呼び出し、次のような SQL ステートメントを生成します。 select * from user where id='1 '; データをクエリし、ターゲット オブジェクトを構築し、それを CGLIB$CALBACK_0.target 属性に割り当てます。このように、中間プロキシ オブジェクトを通じて、Hibernate はエンティティの遅延読み込みを実装します。ユーザーが実際にエンティティ オブジェクトの属性を取得するアクションを開始した場合にのみ、データベース クエリ操作が実際に開始されます。したがって、エンティティの遅延ロードは中間プロキシ クラスを通じて完了するため、エンティティの遅延ロードを使用するのは session.load() メソッドのみです。これは、 session.load() メソッドのみがエンティティのプロキシ クラス オブジェクトを返すためです。クラス。
B. コレクション型の遅延読み込み:
Hibernate の遅延ロード メカニズムの中で、コレクション型の適用はパフォーマンスを大幅に向上させることができるため、最も重要です。この目的のために、Hibernate は JDK コレクションを 1 対 1 で独立して実装するなど、多くの努力を行ってきました。多くの関係では、関連付けられたオブジェクトに対応するために定義する Set コレクションは、java.util.Set 型またはそのサブタイプではなく、カスタム コレクション クラスの実装を使用して net.sf.hibernate.collection.Set 型になります。コレクション型の遅延読み込み。コレクション型に遅延読み込みを使用するには、エンティティ クラスの関連付け部分を次のように構成する必要があります:
<休止状態マッピング>
…
で
&lt; One-many class =” com.neusoft.entity.arrderss”/&gt;
セット>
クラス>
ユーザー user=(User)session.load(User.class,”1”);
コレクション addset=user.getAddresses() (1)
イテレータ it=addset.iterator() (2)
while(it.hasNext()){
アドレス address=(アドレス)it.next();
System.out.println(address.getAddress());
}
プログラムが (1) まで実行されると、関連データをロードするためのクエリは開始されません。(2) まで実行されると、この時点で Hibernate が開始されます。キャッシュ内の修飾データ インデックスを使用して、修飾エンティティ オブジェクトを検索します。ここでは、新しい概念であるデータ インデックスを紹介します。次に、まずデータ インデックスとは何かを見ていきます。 Hibernate でコレクション タイプをキャッシュする場合、コレクション タイプは 2 つの部分に分けてキャッシュされます。まず、コレクション内のすべてのエンティティの ID リストがキャッシュされ、次に、これらのエンティティ オブジェクトの ID リストがキャッシュされます。索引。データ インデックスを検索するときに、対応するデータ インデックスが見つからない場合は、選択 SQL が実行されて修飾されたデータが取得され、エンティティ オブジェクトのコレクションとデータ インデックスが構築され、エンティティ オブジェクトのコレクションが返されて、エンティティが追加されます。オブジェクトとデータのインデックスを Hibernate のキャッシュに追加します。一方、対応するデータインデックスが見つかった場合は、データインデックスから id リストを取り出し、その id に基づいてキャッシュ内で対応するエンティティを検索し、見つかった場合はキャッシュから返します。見つからない場合は、選択 SQL クエリが開始されます。ここでは、パフォーマンスに影響を与える可能性のある別の問題、それがコレクション型のキャッシュ戦略であることがわかります。コレクションタイプを次のように構成すると:
…..
<キャッシュ使用量=”読み取り専用”/>
<1 対多 class=”com.neusoft.entity.Arrderss”/>
セット>
クラス>
ここで、
ユーザー user=(User)session.load(User.class,”1”);
コレクションはaddset=user.getAddresses();
イテレーター it=addset.iterator();
while(it.hasNext()){
アドレス address=(アドレス)it.next();
System.out.println(address.getAddress());
}
System.out.println(“2番目のクエリ……”);
ユーザー user2=(ユーザー)session.load(ユーザー.クラス,”1”);
コレクション it2=user2.getAddresses();
while(it2.hasNext()){
アドレス address2=(アドレス)it2.next();
System.out.println(address2.getAddress());
}
このコードを実行すると、次のような出力が得られます:
id='1';のユーザーから*を選択してください
user_id='1';のアドレスから*を選択してください
天津
大連
2番目のクエリ……
id='1';のアドレスから * を選択してください
id='2';のアドレスから*を選択してください
天津
大連
クエリが 2 回目に実行されると、アドレス テーブルに対して 2 つのクエリ操作が実行されることがわかります。これはなぜでしょうか。これは、エンティティが初めてロードされるとき、コレクション タイプのキャッシュ戦略の構成に従って、コレクション データ インデックスのみがキャッシュされ、コレクション内のエンティティ オブジェクトはキャッシュされないためです。もう一度、Hibernate は対応するエンティティのデータ インデックスを見つけましたが、データ インデックスによると、キャッシュ内で対応するエンティティを見つけることができなかったため、Hibernate は見つかったデータ インデックスに基づいて 2 つの選択 SQL クエリ操作を開始しました。パフォーマンスの無駄が発生しました。この状況を回避するにはどうすればよいでしょうか?コレクション タイプのエンティティのキャッシュ戦略も指定する必要があるため、コレクション タイプを次のように構成する必要があります:
<休止状態マッピング>
<クラス名=”com.neusoft.entity.User” テーブル=”ユーザー”>
…..
<キャッシュの使用法=”読み取り-書き込み”/>
<1 対多 class=”com.neusoft.entity.Arrderss”/>
セット>
この時点で、Hibernate はコレクション タイプのエンティティもキャッシュします。この設定に従って上記のコードを再度実行すると、次のような出力が得られます。
id='1';のユーザーから*を選択してください
user_id='1';のアドレスから*を選択してください
天津
大連
2番目のクエリ……
天津
大連
現時点では、コレクション型に格納されているエンティティ オブジェクトはキャッシュから直接取得できるため、データ インデックスに基づいてクエリを実行する SQL ステートメントはこれ以上ありません。
C. 属性の遅延読み込み:
Hibernate3 では、属性の遅延読み込みという新機能が導入され、高パフォーマンスのクエリを取得するための強力なツールが提供されます。先ほどビッグ データ オブジェクトの読み取りについて説明しましたが、User オブジェクトには履歴書フィールドがあります。このフィールドは java.sql.Clob タイプであり、オブジェクトをロードするときに毎回ロードする必要があります。このフィールドは、本当に必要かどうかに関係なくロードする必要があり、この大きなデータ オブジェクト自体を読み取ると、パフォーマンスに多大なオーバーヘッドが生じます。 Hibernate2 では、前に述べたように、パフォーマンスを細分化して User クラスを分解することによってのみこの問題を解決できます (そのセクションの説明を参照してください)。しかし Hibernate3 では、属性の遅延読み込みメカニズムを使用できるため、このフィールドを操作する必要がある場合にのみ、このフィールドのデータを読み取る機能を取得できるため、エンティティ クラスを次のように構成する必要があります。
<休止状態マッピング>
<クラス名=”com.neusoft.entity.User” テーブル=”ユーザー”>
……
クラス>
Hibernate3 でプロパティの遅延ロードを実装するには、クラス エンハンサーを使用してエンティティ クラスの Class ファイルを拡張します。エンハンサーでは、CGLIB のコールバック メカニズム ロジックをエンティティ クラスに追加します。ここでは、属性の遅延読み込みが依然として CGLIB を通じて実装されていることがわかります。 CGLIB は Apache のオープンソース プロジェクトであり、このクラス ライブラリは Java クラスのバイトコードを操作し、バイトコードに基づいて要件を満たすクラス オブジェクトを動的に構築できます。上記の設定に基づいて、次のコードを実行します:
文字列 sql=”from ユーザー user where user.name=’zx’ ”;
クエリクエリ=session.createQuery(sql); (1)
リスト list=query.list();
for(int i=0;i
System.out.println(user.getName());
System.out.println(user.getResume()); (2)
}
実行が (1) に達すると、次のような SQL ステートメントが生成されます:
name=’zx’;www.2cto.com
のユーザーからID、年齢、名前を選択してくださいこのとき、Hibernate は User エンティティ内のすべての非遅延読み込み属性に対応するフィールド データを取得します。実行が (2) に達すると、次のような SQL ステートメントが生成されます。
id='1';のユーザーから履歴書を選択してください
このとき、実際のレジュームフィールドデータの読み出し動作が開始される。
著者: oh_モウリーニョ