(تحديث () التحديثات، إذا لم يكن هناك مفتاح أساسي، سيتم الإبلاغ عن خطأ.
saveOrUpdate() يحفظ أو يحدّث، وينفذ عملية الإدراج بدون مفتاح أساسي.
التحديث: إنها عملية تحديث عابرة (عابرة) أو منفصلة فقط (منفصلة). عادة لا يكون لعملية التحديث للكائنات المنفصلة أي تأثير. وتصبح حالة الكائن أيضًا كائنًا مُدارًا
SaveOrUpdate: يعمل أيضًا على العمليات المؤقتة أو المنفصلة أما بالنسبة للإدراج أو التحديث فيجب تحليله وفقًا لبعض الشروط المحددة في المعرف. ومع ذلك، أعتقد شخصيًا أنه عندما يكون من الواضح أن عملية الإدراج فقط ستحدث، فمن الأفضل تجنب استخدام saveOrUpdate واستخدام الحفظ مباشرةً)
لنبدأ ببعض المفاهيم:
في السبات، المفهوم الأساسي هو إدارة حالة أمر الشراء. يحتوي أمر الشراء على ثلاث حالات:
1. VO غير مستمر
في هذا الوقت، هو كائن ذاكرة VO، وتتم إدارة دورة الحياة بواسطة JVM.
2. استمر أمر الشراء، ويتم تعيين بيانات قاعدة البيانات في هذا الوقت خلال دورة حياة الجلسة، وتدير قاعدة البيانات دورة الحياة.
3. لقد استمر، ولكن تم فصله الآن عن الجلسة إذا قمت بتشغيل أمر الشراء هذا الذي تم فصله عن الجلسة باعتباره VO، فيمكنك أيضًا الدخول إلى جلسة أخرى ومتابعة إدارة حالة أمر الشراء في هذا الوقت ، يصبح PO الحالة الثانية. هذا النوع من أوامر الشراء يتقاطع بالفعل
تقوم الجلسة بصيانة الحالة.
في JDO1.x التقليدي، يحتوي PO على الحالتين الأوليين فقط. بمجرد فصل PO عن PM، فإنه يفقد حالته ولم يعد مرتبطًا ببيانات قاعدة البيانات، ويصبح VO للذاكرة فقط.
حتى لو قمت بإضافة PM جديد، لا يمكن استعادة حالته.
تكمن قوة السبات في أنه بعد مغادرة أمر الشراء للجلسة، لا يزال بإمكانه الحفاظ على الحالة، وبعد الدخول إلى جلسة جديدة، يتم استعادة القدرة على إدارة الحالة
تحتاج إلى استخدام session.update أو session.saveOrUpdate، وهو ما ذكره مرجع السبات في "يتطلب برمجة مختلفة قليلاً
نموذج"
الآن أدخل هذا الموضوع رسميًا:
ببساطة، يتم استخدام التحديث والحفظ أو التحديث لإدارة حالة أوامر الشراء عبر الجلسات.
بافتراض أن أمر الشراء الخاص بك لا يحتاج إلى تجاوز الجلسات، فلا داعي لاستخدامه. على سبيل المثال، إذا قمت بفتح جلسة وتشغيل أمر الشراء ثم إغلاقه، فلن تستخدم أمر الشراء هذا مرة أخرى.
ثم ليست هناك حاجة لاستخدام التحديث.
لذلك دعونا ننظر إلى المثال أعلاه:
كود جافا
Foo foo=sess.load(Foo.class,id);;
foo.setXXX(xxx);;
sess.flush();;
sess.commit();;
Foo foo=sess.load(Foo.class,id);;
تكتمل جميع عمليات كائن PO foo خلال دورة حياة الجلسة، لذلك ليست هناك حاجة لإجراء عمليات بشكل صريح مثل sess.update(foo). سوف يكتشف السبات تلقائيًا وجود كائن foo
تم تعديله، لذلك يتم إرسال تحديث SQL إلى قاعدة البيانات. بالطبع، ليس من الخطأ أن تصر على إضافة sess.update(foo)، لكن لا داعي لذلك.
تعني الجلسة المتقاطعة أنه بعد إغلاق الجلسة، ستظل تستخدم كائن أمر الشراء هذا باعتباره VO، ثم تقوم لاحقًا بتعديل خصائصه خارج الجلسة، ثم تريد فتحه مرة أخرى.
افتح جلسة واحفظ تعديلات سمة VO في قاعدة البيانات، ثم ستحتاج إلى استخدام التحديث.
كود جافا
// في الجلسة الأولى
Cat cat = (Cat); firstSession.load(Cat.class, catId);;
Cat المحتملةMate = new Cat();;
firstSession.save(potentialMate);;
// في مستوى أعلى من التطبيق
cat.setMate(potentialMate);;
// لاحقًا، في جلسة جديدة
SecondSession.update(cat);;/تحديث القط
SecondSession.update(mate);;/تحديث زميل
// في الجلسة الأولى Cat cat = (firstSession.load(Cat.class, catId);;
firstSession.save(potentialMate);; // في طبقة أعلى من التطبيق cat.setMate(potentialMate);;
جلسة جديدة SecondSession.update(cat);; // تحديث القطة SecondSession.update(mate);;
يتم الحصول على كائنات cat وmate في الجلسة الأولى، بعد إغلاق الجلسة الأولى، ويصبحان الحالة الثالثة لـ PO، وPO الذي تم فصله عن الجلسة في هذا الوقت
لا يزال يتم الاحتفاظ بمعلومات حالتهم. وعندما يدخلون الجلسة الثانية، يمكنهم تحديث الحالة على الفور. ولكن بسبب عملية التعديل على القط: cat.setMate
(potentialMate)؛ لا يمكن أن يعرف السبات أن كائن القط قد تم تعديله، ولا يعرف هذا التعديل، لذلك يجب أن يكون صريحًا.
اتصل بـ SecondSession.update(cat); لإعلام Hibernate بأن كائن cat قد تم تعديله ويجب عليك إرسال تحديث sql.
لذلك هذا هو دور التحديث، ولن تتم كتابته إلا عندما يقوم كائن أمر الشراء بمزامنة حالته عبر الجلسات. عندما لا يلزم معالجة كائن أمر الشراء عبر الجلسات،
عند تنفيذ إدارة الحالة، ليست هناك حاجة لكتابة التحديثات.
لنتحدث عن استخدام saveOrUpdate:
يكمن الفرق بين saveOrUpdate والتحديث في الإستراتيجية التي يتبناها Hibernate لأمر الشراء في إدارة حالة أمر الشراء عبر الجلسات.
على سبيل المثال، عندما تكتب DAOImpl، قم بإضافة mate إلى الكائن cat، كما هو محدد أدناه:
كود جافا
public void addMate(Cat cat, Mate mate {);
جلسة الجلسة = ...;
ترانساكتون تكساس = ...;
تحديث الجلسة(قطة);;
cat.addMate(mate);;
tx.commit();;
جلسة. إغلاق ()؛؛
};
public void addMate(Cat cat, Mate mate { جلسة الجلسة = ...;
cat.addMate(mate);;
من الواضح أنك تحتاج إلى تغليف عمليات السبات في DAO، بحيث لا يحتاج مبرمجو طبقة الأعمال ومبرمجو طبقة الويب إلى معرفة السبات والاتصال مباشرة بـ DAO.
عند هذه النقطة تنشأ المشكلة: هناك شرط أساسي ضروري لكي يعمل الكود أعلاه بشكل صحيح، أي أن كائن معلمة استدعاء الأسلوب يجب أن يكون أمر شراء مستمرًا، أي أنه يجب أن يكون
قم أولاً بالاستعلام عنه من قاعدة البيانات ثم استخدمه على هذا النحو. لكن من الواضح أن المبرمجين في طبقة الأعمال لا يعرفون هذا اللغز الداخلي إذا كان عمله هو إضافة قطة بين الحين والآخر
من الواضح أنه سوف يسميها هكذا، سيظهر كائن قطة جديد، ثم أضفMate:
كود جافا
قطة قطة = قطة جديدة();;
cat.setXXX();;
daoimpl.addMate(cat,mate);;
قطة قطة = قطة جديدة();; cat.setXXX();;
ولكن يرجى ملاحظة أن كائن القط هذا هو مجرد أمر VO، ولم يتم استمراره، وهو ليس أمر شراء، وهو غير مؤهل لاستدعاء أسلوب addMate، لذا فإن استدعاء أسلوب addMate لن يذهب فعليًا إلى
لإرسال تحديث SQL إلى قاعدة البيانات، يجب حفظ كائن cat في قاعدة البيانات أولاً فقط بعد أن يصبح أمر شراء حقيقي، يمكن تأهيله لـ addMate.
عليك أن تفعل ذلك مثل هذا:
كود جافا
قطة قطة = قطة جديدة();;
cat.setXXX();;
daoimpl.addCat(cat);;
daoimpl.addMate(cat, mate);;
Cat cat = new Cat();; daoimpl.addCat(cat);;
قم بإصرار القطة أولاً، ثم قم بإجراء عمليات الثبات الأخرى على القطة. لذلك، يجب على المبرمجين في طبقة الأعمال معرفة الحالة التي يوجد بها كائن القط، سواء كان الأول أو الثالث.
إذا كان هذا هو النوع الأول، فأنت بحاجة إلى الحفظ أولاً ثم addMate إذا كان النوع الثالث، فما عليك سوى addMate مباشرة.
لكن الشيء الأكثر خطورة هو أنه إذا كان البرنامج بأكمله يحتوي على عدة طبقات، فقد يكون كائن القط الذي يحصل عليه مبرمج طبقة الأعمال هو القط الذي تم تمريره من طبقة تطبيق الويب العليا، وهو نفسه لا يعرف ذلك.
سواء كان cat VO، أو لم يستمر، أو استمر، فليس لديه أي طريقة لكتابة برنامج على الإطلاق.
من الواضح أن مثل هذا DAOImpl يمثل مشكلة وسيتسبب في العديد من مصائد البرمجة لمبرمجي طبقة الأعمال. يجب أن يكون لدى مبرمجي طبقة الأعمال فهم عميق لكل زوج من أزواج DAO التي يطلقون عليها.
أي نوع من إدارة الحالة يتم تنفيذه، يجب أن يكون لديك فهم عميق للحالة الدقيقة لكائن أمر الشراء الخاص به في أي وقت لضمان صحة البرمجة، من الواضح أن هذا مستحيل، ولكن مع
saveOrUpdate، يتم حل هذه المشكلات بسهولة.
أنت الآن بحاجة إلى تعديل طريقة addMate:
كود جافا
public void addMate(Cat cat, Mate mate {);
جلسة الجلسة = ...;
ترانساكتون تكساس = ...;
session.saveOrUpdate(cat);;
cat.addMate(mate);;
tx.commit();;
جلسة. إغلاق ()؛؛
};
public void addMate(Cat cat, Mate mate { جلسة الجلسة = ...;
(cat)؛؛ cat.addMate(mate);;
كما هو مذكور أعلاه، إذا مرر مبرمج طبقة الأعمال كائن أمر الشراء الذي استمر، فسيقوم السبات بتحديث كائن القط (على افتراض أن مبرمج طبقة الأعمال قام بتعديله خارج الجلسة)
cat)، إذا كان ما تم تمريره كائنًا جديدًا، فاحفظ كائن PO في قاعدة البيانات.
راجع للشغل: ما إذا كان الإسبات يقوم بتحديث كائن القطة أو حفظ كائن القطة في هذا الوقت يعتمد على إعداد قيمة عدم الحفظ.
بهذه الطريقة، لم يعد المبرمجون في طبقة الأعمال مضطرين للقلق بشأن حالة أمر الشراء. بالنسبة لهم، لا يهم ما إذا كان cat كائنًا جديدًا، أو مجرد VO، أو تم الاستعلام عنه من قاعدة البيانات.
بغض النظر عن كائنات أمر الشراء، يمكن إضافتها جميعًا مباشرةً إلى addMate:
كود جافا
daoimple.addMate(cat, mate);;
daoimple.addMate(cat, mate);;
وهذا ما يفعله saveOrUpdate.
هذه المقالة مأخوذة من مدونة CSDN، يرجى الإشارة إلى المصدر عند إعادة الطباعة: http://blog.csdn.net/zhrl0000/archive/2009/12/17/5027965.aspx.
-