web-dev-qa-db-ja.com

Hibernateの遅延読み込みとは何ですか?

Javaの遅延読み込みとは何ですか?私はそのプロセスを理解していません。誰かが遅延読み込みのプロセスを理解するのを手伝ってくれますか?

163
rocker

あなたには親があり、その親には子のコレクションがあるとします。 Hibernateは、子を「遅延ロード」できるようになりました。つまり、親をロードするときに、すべての子を実際にロードするわけではありません。代わりに、要求されたときにそれらをロードします。これを明示的に要求するか、これがはるかに一般的であるため、hibernateは子にアクセスしようとすると自動的にそれらをロードします。

遅延ロードは、多くの場合、子を必要としないためロードされないため、パフォーマンスの大幅な向上に役立ちます。

N + 1問題にも注意してください。 Hibernateは、コレクションにアクセスするときに実際にすべての子をロードしません。代わりに、各子を個別にロードします。コレクションを反復処理すると、すべての子に対してクエリが発生します。これを避けるために、休止状態をだましてすべての子を同時にロードすることができます。 parent.getChildren()。size()を呼び出します。

256
Thomas Lötzer

「遅延読み込み」とは、エンティティが実際にアクセスしたときに、エンティティがonly読み込まれることを意味しますfirst時間。

パターン は次のようになります。

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}

これにより、all事前に大きなデータセット内のエンティティを事前ロード/事前入力するコストを節約できますが、実際にはall /は必要ありません そのうちの。

Hibernateでは、子エンティティのコレクションを遅延ロードするように構成できます。 actual遅延読み込みは、Hibernateがコレクションの割り当てに「内部」を使用する PersistentSet のメソッド内で実行されますSetとしてのエンティティ。

例えば。

public class Parent {
    private Set<Child> children;

    public Set<Child> getChildren() {
        return children;
    }
}

public void doSomething() {
    Set<Child> children = parent.getChildren(); // Still contains nothing.

    // Whenever you call one of the following (indirectly), 
    // Hibernate will start to actually load and fill the set.
    children.size();
    children.iterator();
}
70
BalusC

Martin Fowlerは Lazy Load パターンを Patterns of Enterprise Application Architecture で定義しています:

必要なすべてのデータを含んでいないが、それを取得する方法を知っているオブジェクト。

したがって、特定のオブジェクトをロードするときのアイデアは、熱心なロードではなく、関連するパフォーマンスを保存するためにすぐには使用できない関連オブジェクトですコスト。代わりに、関連するオブジェクトは使用されたときにのみロードされます。

これは、データアクセスとHibernateに固有のパターンではありませんが、このようなフィールドで特に役立ちます。Hibernateは、1対多の関連付けと単一ポイントの関連付け(1対1および多対1)の遅延読み込みもサポートします特定の条件下で。遅延対話については、Hibernate 3.0リファレンスドキュメントの Chapter 19 で詳しく説明しています。

24
Pascal Thivent

デフォルトでは、遅延読み込みはtrueです。遅延読み込みは、選択クエリが実行されたときにデータベースにヒットしないことを意味します。ゲッター関数を待機します。つまり、必要に応じて、datbaseからフェッチします。たとえば、あなたはたくさんのおもちゃを持った子供を持つ親です。しかし、現在の問題は、あなたが彼に電話するときはいつでも(あなたには男の子がいると思います)、彼はすべての彼のおもちゃもあなたに来ます。彼がいつも彼のおもちゃを持ち歩くことを望まないので、これは問題です。したがって、合理的な親であるあなたは、先に進み、子供のおもちゃをLAZYと定義します。今あなたが彼を呼ぶときはいつでも、彼は彼のおもちゃなしでちょうどあなたのところに来ます。

15

遅延フェッチは、親オブジェクトのロード中に子オブジェクトをロードするかどうかを決定します。この設定は、親クラスのそれぞれの休止状態マッピングファイルで行う必要があります。 Lazy = true(子をロードしないことを意味します)デフォルトでは、子オブジェクトの遅延ロードはtrueです。

これにより、親でgetChild()メソッドを呼び出してアプリケーションで明示的に呼び出されない限り、子オブジェクトがロードされないようにします。この場合、getChild()が親オブジェクトで実際に呼び出されると、hibernateは新しいデータベース呼び出しを発行して子をロードします。

ただし、場合によっては、親がロードされるときに子オブジェクトをロードする必要があります。 lazy = falseを設定するだけで、データベースから親がロードされるとhibernateは子をロードします。

例:テーブルがある場合EMPLOYEEはEmployeeオブジェクトにマップされ、Addressオブジェクトのセットが含まれます。親クラス:従業員クラス、子クラス:住所クラス

public class Employee { 
private Set address = new HashSet(); // contains set of child Address objects 
public Set getAddress () { 
return address; 
} 
public void setAddresss(Set address) { 
this. address = address; 
} 
} 

Employee.hbm.xmlファイル内

<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set> 

上記の構成。 lazy="false"の場合:-Employeeオブジェクトをロードすると、その時点で子オブジェクトAddressもロードされ、setAddresss()メソッドに設定されます。 employee.getAdress()を呼び出すと、ロードされたデータが返されます。新しいデータベース呼び出しはありません。

lazy="true"の場合:-これがデフォルト設定です。言及しない場合、休止状態はlazy = trueを考慮します。 Employeeオブジェクトをロードすると、その時点で子オブジェクトAdressはロードされません。アドレスオブジェクトを取得するには、データベースへの追加の呼び出しが必要です。 employee.getAdress()を呼び出すと、その時点でデータベースクエリが起動し、結果が返されます。新鮮なデータベース呼び出し。

11
Bhavin Shah

素人の言葉では、まるでケーキを作っているようで、冷蔵庫から5〜10個の材料が必要になります。 2つの選択肢があります。冷蔵庫からすべての材料を取り出してキッチンのプラットフォームに置くか、必要なときに必要なものを持ち込みます。

同様に、Eager Loadingでは、Beanとその関連クラス(子でもis-a関係でもない、ケーキ、小麦粉、牛乳、クリームなど)に関するすべての情報を取得します。遅延読み込みの場合は、最初に同じテーブルから得られた識別子と値のみを持ち込みます(ケーキの場合、ボウルに最初に必要な必要な材料)。他のテーブルからのすべての情報は、必要に応じて/使用されるときにフェッチされます。

8
Keyur

遅延読み込み?まあ、それは単に子レコードがすぐにフェッチされるのではなく、それらにアクセスしようとすると自動的にフェッチされることを意味します。

8
Steffen

遅延設定は、親オブジェクトのロード中に子オブジェクトをロードするかどうかを決定します。この設定を行う必要があるのは、それぞれの親クラスの休止状態マッピングファイルです。Lazy= true(子をロードしないことを意味します) 。これにより、親のgetChild()メソッドを呼び出してアプリケーションで明示的に呼び出されない限り、子オブジェクトがロードされないことが保証されます。 object。しかし、場合によっては、親がロードされるときに子オブジェクトをロードする必要があります。 lazy = falseにするだけで、親がデータベースからロードされるとhibernateが子をロードします。Exampleslazy= true(デフォルト)Userクラスのアドレスの子は、頻繁に必要でない場合は遅延させることができます。lazy= falseオンライン書店の本を扱うときはいつでも、Book親のAuthorオブジェクト。

3
Siva Chimpiri

遅延読み込みは、コンピュータープログラミングで一般的に使用されるデザインパターンであり、オブジェクトの初期化を必要な時点まで延期します。適切かつ適切に使用すれば、プログラムの動作の効率化に貢献できます。

ウィキペディア

Lazy Loading hibernate.orgからのリンク

2
Diego Dias

まあ、それは単にあなたが今使用しないであろうデータ全体を一度にロードするのではなく、現在必要なデータをロードすることを意味します。これにより、アプリケーションのロード時間が通常よりも速くなります。

0
Abhinaya Pandey

遅延読み込みを使用すると、関連付けの取得を延期したり、フェッチ戦略をより適切に制御したりできます。

EAGERロードを使用する場合、クエリ時にオーバーライドできないグローバルフェッチプランを定義します。つまり、エンティティモデルの設計中に行った決定に限定されます。 EAGERフェッチはコードのにおいです 。フェッチ戦略はクエリ時のポリシーであり、ビジネスユースケースごとに異なる可能性があるためです。

フェッチ戦略 は非常に重要な側面です。EAGERフェッチが多すぎると、パフォーマンスに関連する深刻な問題が発生する可能性があるためです。

0
Vlad Mihalcea

Hiberanteは、エンティティとコレクションの両方の遅延初期化の機能をサポートします。 Hibernateエンジンは、クエリ対象のオブジェクトのみを読み込み、他のエンティティまたはコレクションは読み込みません。

lazy = "false"は、デフォルトでは、唯一の子の初期化記述の読み込みはlazyです。trueの場合、親は読み込みで子はサポートされません

0
abburi

遅延設定は、親オブジェクトのロード中に子オブジェクトをロードするかどうかを決定します。この設定を行う必要があるのは、それぞれの親クラスの休止状態マッピングファイルです。Lazy= true(子をロードしないことを意味します) 。

驚いたことに、画面の背後で休止状態にしたことによってどのように達成されるかについての回答はありません。

遅延ローディングは、パフォーマンス上の理由で休止状態で効果的に使用される設計パターンであり、次の手法が含まれます。


1。バイトコード計測

Hibernate hooks を使用して基本クラス定義を拡張し、そのエンティティオブジェクトへのすべての呼び出しをインターセプトします。

コンパイル時または実行[ロード]時に実行されます

1.1コンパイル時間

  • コンパイル後の操作

  • 主にmaven/antプラグインによって

1.2実行時間

  • コンパイル時のインストルメンテーションが行われない場合、実行時に作成されます javassist のようなライブラリを使用して

2。プロキシ

Hibernateが返すエンティティオブジェクトは、実際の型のプロキシです。

参照: Javassist。主なアイデアは何で、どこで実際に使用されますか?

0
147.3k