(update() は更新を行いますが、主キーがない場合はエラーが報告されます。
saveOrUpdate() は、主キーなしで保存または更新し、挿入を実行します。
更新: これは、一時的 (一時的) または単に分離された (分離された) オブジェクトの更新操作です。通常、分離されたオブジェクトの場合は、同期操作が実行されます。つまり、データベースのデータが変更されます。そしてオブジェクトの状態も管理オブジェクトになります
SaveOrUpdate: 一時的な操作または切り離された操作でも動作します。挿入するか更新するかについては、ID で指定された特定の条件に従って分析する必要があります。ただし、個人的には、挿入操作のみが発生することが明らかな場合は、saveOrUpdate の使用を避け、直接 save を使用した方がよいと思います)
いくつかの概念から始めましょう。
Hibernate では、中心となる概念は PO の状態管理です。 PO には 3 つの状態があります。
1. 持続しない VO
このとき、メモリオブジェクトVOとなり、ライフサイクルはJVMによって管理されます。
2. PO は永続化されており、この時点でセッション ライフ サイクル中にデータベース データがマッピングされ、データベースがライフ サイクルを管理します。
3. 永続化されましたが、現在はセッションから切り離されています。セッションから切り離されたこの PO を VO として実行すると、この時点で別のセッションに入って PO の状態を管理し続けることもできます。 、PO になります。この種のPOは実際に交差します
セッションは状態のメンテナンスを実行します。
従来の JDO1.x では、PO は最初の 2 つの状態しか持ちません。PO が PM から分離されると、その状態は失われ、純粋なメモリ VO になります。
新たにPMを追加しても、その状態は復元できません。
Hibernate の強みは、PO がセッションを離れた後も、新しいセッションに入った後も状態管理機能が復元されることです。
session.update または session.saveOrUpdate を使用する必要があります。これは、「Hibernate Reference」で説明されているものであり、少し異なるプログラミングが必要です
モデル"
ここで正式にこのトピックに入ります。
簡単に言えば、update と saveOrUpdate は、クロスセッション PO のステータスを管理するために使用されます。
PO がセッションをまたぐ必要がない場合は、それを使用する必要はありません。たとえば、セッションを開いて PO を操作し、その後閉じた場合、この PO は再度使用されません。
その場合、アップデートを使用する必要はありません。
それでは、上記の例を見てみましょう。
Javaコード
Foo foo=sess.load(Foo.class,id);;
foo.setXXX(xxx);;
sess.flush();;
sess.commit();;
Foo foo=sess.load(Foo.class,id);; foo.setXXX(xxx);; sess.commit();;
PO オブジェクト foo の操作はすべてセッションのライフサイクル内で完了するため、sess.update(foo) などの操作を明示的に実行する必要はありません。 Hibernate は、foo オブジェクトが
が変更されているため、更新 SQL がデータベースに送信されます。もちろん、sess.update(foo) を追加することに固執するのは間違いではありませんが、そうする必要はありません。
クロスセッションとは、セッションが閉じられた後も、この PO オブジェクトを引き続き VO として使用し、後でそのプロパティをセッション外で変更し、再度開くことを意味します。
セッションを開き、VO 属性の変更をデータベースに保存してから、更新を使用する必要があります。
Javaコード
// 最初のセッションで
猫 cat = (猫); firstSession.load(Cat.class, catId);;
Cat の潜在的なMate = new Cat();;
firstSession.save(potentialMate);;
// アプリケーションの上位層で
cat.setMate(potentialMate);;
// 後で、新しいセッションで
SecondSession.update(cat); // 猫を更新します。
SecondSession.update(mate); // メイトを更新します
// 最初のセッションで Cat cat = (Cat); firstSession.load(Cat.class, catId);;
firstSession.save(potentialMate); // アプリケーションの上位層で cat.setMate(potentialMate); // 後で、
新しいセッション SecondSession.update(cat); // 猫を更新します SecondSession.update(mate); // メイトを更新します
cat オブジェクトと mate オブジェクトは最初のセッションで取得され、最初のセッションが終了すると、PO の 3 番目の状態になり、この時点でセッションが切り離されます。
ステータス情報は引き続き保持されます。 2 番目のセッションに入ると、すぐにステータスを更新できます。ただし、cat の変更操作のため: cat.setMate
(potentialMate); Hibernate は、cat オブジェクトが変更されたことを認識できないため、明示的に行う必要があります。
SecondSession.update(cat); を呼び出して、cat オブジェクトが変更されたため、更新 SQL を送信する必要があることを Hibernate に通知します。
したがって、これは更新の役割です。これは、PO オブジェクトがセッション間でステータスを同期しているときにのみ書き込まれます。 PO オブジェクトをセッション間で処理する必要がない場合、
状態管理を行う場合、更新を記述する必要はありません。
saveOrUpdate の使用について話しましょう。
saveOrUpdate と update の違いは、クロスセッション PO 状態管理において Hibernate が PO に採用する戦略にあります。
たとえば、DAOImpl を作成するときは、以下に定義されているように、cat オブジェクトにメイトを追加します。
Javaコード
public void addMate(猫猫, メイトメイト);
セッション session = ...;
トランザクション tx = ...;
session.update(猫);;
cat.addMate(メイト);;
tx.commit();;
session.close();;
};
public void addMate(Cat cat, Mate mate); { セッションセッション = ... トランザクション tx = ...;
cat.addMate(mate);; tx.commit();;
明らかに、ビジネス層のプログラマと Web 層のプログラマが Hibernate を知っていて DAO を直接呼び出す必要がないように、Hibernate 操作を DAO にカプセル化する必要があります。
この時点で問題が発生します。上記のコードが正しく実行されるためには必要な前提条件があります。つまり、メソッド呼び出しパラメータの cat オブジェクトは永続化された PO である必要があります。
まずデータベースからクエリを実行してから、次のように使用します。しかし、ビジネス層のプログラマーは、猫を追加することが彼のビジネスである場合、この内部謎を明らかに知りません。
その仲間、彼は明らかにそれを次のように呼びます。新しい猫オブジェクトが出てきて、addMate します。
Javaコード
猫猫 = new Cat();;
cat.setXXX();;
daoimpl.addMate(猫,メイト);;
猫猫 = 新しい猫();; daoimpl.addMate(猫,メイト);;
ただし、この cat オブジェクトは単なる VO であり、永続化されておらず、PO ではなく、addMate メソッドを呼び出す資格がないため、addMate メソッドを呼び出しても実際には
データベース内の更新 SQL を送信するには、最初に cat オブジェクトをデータベースに保存する必要があります。それが実際に PO になった後でのみ、addMate の資格を得ることができます。
次のようにする必要があります。
Javaコード
猫猫 = new Cat();;
cat.setXXX();;
daoimpl.addCat(猫);;
daoimpl.addMate(猫, メイト);;
猫猫 = 新しい猫 ();; daoimpl.addCat(猫);;
最初に cat を永続化し、次に cat に対して他の永続化操作を実行します。したがって、ビジネス層のプログラマは、cat オブジェクトが最初の状態であるか 3 番目の状態であるかを把握する必要があります。
最初のタイプの場合は、最初に保存してから addMate する必要があります。3 番目のタイプの場合は、直接 addMate するだけです。
しかし、最も致命的なのは、ソフトウェア全体が多数の層を持つ場合、ビジネス層のプログラマが取得する猫オブジェクトが、上位の Web アプリケーション層から渡された猫である可能性があり、それがプログラマ自身には分からないことです。
cat が VO であっても、永続化されていない場合でも、永続化されている場合でも、彼にはプログラムを書く方法がまったくありません。
そのため、このような DAOImpl には明らかに問題があり、ビジネス層のプログラマは、呼び出す各 DAO ペア PO ペアを深く理解する必要があります。
どのような状態管理が実行されるのか、プログラミングの正確性を確保するには、いつでも PO オブジェクトの正確な状態を深く理解する必要があります。これは明らかに不可能ですが、
saveOrUpdate を使用すると、これらの問題は簡単に解決されます。
ここで、addMate メソッドを変更する必要があります。
Javaコード
public void addMate(猫猫, メイトメイト);
セッション session = ...;
トランザクション tx = ...;
session.saveOrUpdate(cat);;
cat.addMate(メイト);;
tx.commit();;
session.close();;
};
public void addMate(Cat cat, Mate mate); { セッションセッション = ... トランザクション tx = ...;
(猫);; 猫.addMate();; セッション.閉じる();;
上記のように、ビジネス層プログラマが永続化された PO オブジェクトを渡すと、Hibernate は cat オブジェクトを更新します (ビジネス層プログラマがセッション外でそれを変更したと仮定します)。
cat 属性)、渡されたものが新しいオブジェクトの場合は、PO オブジェクトをデータベースに保存します。
ところで: この時点で Hibernate が cat オブジェクトを更新するか、cat オブジェクトを保存するかは、unsave-value の設定によって決まります。
このようにして、ビジネス層のプログラマーは、cat が新しいオブジェクトであるか、単なる VO であるか、データベースからクエリされたものであるかは関係なく、PO のステータスを気にする必要がなくなります。
PO オブジェクトに関係なく、それらはすべて addMate に直接追加できます。
Javaコード
daoimple.addMate(猫, メイト);;
daoimple.addMate(猫, メイト);;
これがsaveOrUpdateの動作です。
この記事は CSDN ブログからのものです。転載する場合は出典を明記してください: http://blog.csdn.net/zhrl0000/archive/2009/12/17/5027965.aspx
-