この記事では、セッションおよびバッチ操作を管理するための Hibernate の使用法を詳細に分析します。皆さんの参考に共有してください。具体的な分析は次のとおりです。
Hibernate はセッションを管理します
Hibernate 自体は、Session オブジェクトを管理する 3 つの方法を提供します。 ① Session オブジェクトのライフ サイクルはローカル スレッドにバインドされます。 ② Session オブジェクトのライフ サイクルは JTA トランザクションにバインドされます。 ③ Hibernate デリゲート プログラムは Session オブジェクトのライフ サイクルを管理します。
Hibernate 設定ファイルでは、hibernate.current_session_context_class 属性を使用してセッション管理メソッドを指定します。オプションの値は次のとおりです。
① スレッド: Session オブジェクトのライフ サイクルはローカル スレッドにバインドされます。 ② jta*: Session オブジェクトのライフ サイクルは JTA トランザクションにバインドされます。 ③ マネージド: Session オブジェクトのライフ サイクルを管理する Hibernate デリゲート プログラム
Session オブジェクトのライフサイクルはローカル スレッドにバインドされています。
Hibernate 設定ファイルの hibernate.current_session_context_class 属性値が thread に設定されている場合、Hibernate はローカル スレッドにバインドされた方法でセッションを管理します。
Hibernate は、次のルールに従ってセッションをローカル スレッドにバインドします。
スレッド (スレッド) が SessionFactory オブジェクトの getCurrentSession() メソッドを初めて呼び出すと、このメソッドは新しいセッション (sessionA) オブジェクトを作成し、そのオブジェクトを threadA にバインドし、threadA が SessionFactory オブジェクトを再度呼び出すときにセッションを返します。 getCurrentSession() メソッドを使用すると、このメソッドは sessionA オブジェクトを返します。threadA が sessionA オブジェクトに関連付けられたトランザクションを送信すると、Hibernate は自動的にフラッシュします。 sessionA オブジェクトをキャッシュし、必要に応じてトランザクションをコミットしてセッションを閉じます。 threadA が sessionA オブジェクトに関連付けられたトランザクションをキャンセルすると、 sessionA オブジェクトも自動的に閉じられます。 threadA が SessionFactory オブジェクトの getCurrentSession() メソッドを再度呼び出すと、このメソッドは新しい Session (sessionB) オブジェクトを作成し、そのオブジェクトをバインドします。 threadA を返し、セッション B を返します。
データをバッチで処理する
データのバッチ処理とは、大量のデータを1つのトランザクションで処理することを指し、アプリケーション層の処理でバッチ処理を行う主な方法は次のとおりです。
① セッションを通して
②HQLに合格する
③ StatelessSession経由
④ JDBC API経由 ----最速のため推奨
セッションはバッチ操作を実行します。
セッションの save() メソッドと update() メソッドは、処理されたオブジェクトを独自のキャッシュに保存します。 Session オブジェクトを使用して多数の永続オブジェクトを処理する場合、処理済みで再度アクセスされないオブジェクトは、適時にキャッシュから空にする必要があります。具体的な方法は、オブジェクトまたはオブジェクトの小さなバッチを処理した後、すぐに flash() メソッドを呼び出してキャッシュを更新し、その後、clear() メソッドを呼び出してキャッシュをキャッシュすることです。
セッションを介した処理操作には、次の制約があります。
JDBC の単一バッチ処理の数は、Hibernate 構成ファイルで設定する必要があります。毎回データベースに送信される SQL ステートメントのバッチ数がバッチ サイズ属性と一致していることを確認する必要があります。
オブジェクトが「identity」識別子ジェネレーターを使用している場合、Hibernate は JDBC でバッチ挿入操作を実行できません。
バッチ操作を実行するときは、Hibernate の 2 次キャッシュをオフにすることをお勧めします。
データをバッチ挿入するコードのデモ:
コードをコピーすると、コードは次のようになります。 News news = null;
for(int i = 0; i < 10000; i++) {
ニュース = 新しいニュース();
news.setTitle("--" + i);
session.save(ニュース);
if((i + 1) % 20 == 0) {
セッション.flush();
session.clear();
}
}
バッチ更新:バッチ更新を実行する場合、すべてのオブジェクトを一度にセッション キャッシュにロードし、キャッシュ内で 1 つずつ更新することは明らかにお勧めできません。
スクロール可能な結果セット org.hibernate.ScrollableResults を使用します。このオブジェクトには実際にはオブジェクトは含まれず、オンラインでレコードを検索するために使用されるカーソルのみが含まれます。プログラムが ScrollableResults オブジェクトの特定の要素にアクセスするためにトラバースする場合にのみ、対応するオブジェクトがデータベースにロードされます。
org.hibernate.ScrollableResults オブジェクトは、Query のスクロール メソッドによって返されます。
HQL によるバッチ操作:
注: HQL は、INSERT INTO...SELECT 形式の挿入ステートメントのみをサポートしますが、INSERT INTO...VALUES 形式の挿入ステートメントはサポートしません。したがって、HQL を使用してバッチ挿入操作を実行することはできません。
StatelessSession によるバッチ操作:
正式には、StatelessSession の使用法は Session と似ています。 Session と比較すると、StatelessSession には次の違いがあります。
StatelessSession にはキャッシュがなく、StatelessSession を通じてロード、保存、または更新されたオブジェクトはフリー状態です。
StatelessSession は Hibernate の 2 番目のレベルのキャッシュと対話しません。StatelessSession の save()、update()、または delete() メソッドを呼び出すと、これらのメソッドは 1 つの SQL ステートメントの実行だけを計画するのではなく、対応する SQL ステートメントを即座に実行します。
StatelessSession はダーティ チェックを実行しないため、Customer オブジェクトのプロパティを変更した後、StatelessSession の update() メソッドを呼び出してデータベース内のデータを更新する必要があります。
StatelessSession は、関連付けられたオブジェクトに対してカスケード操作を実行しません。OID 1 の Customer オブジェクトは、同じ StatelessSession オブジェクトを通じて 2 回ロードされます。取得された 2 つのオブジェクトのメモリ アドレスは異なります。
StatelessSession によって実行される操作は、Interceptor インターセプターによってキャプチャできますが、Hibernate のイベント処理システムによって無視されます。
この記事が皆さんの Java プログラミングに役立つことを願っています。