يركز البحث في هذه المقالة بشكل أساسي على آلية ذاكرة التخزين المؤقت للإسبات ، على النحو التالي.
student.java:
طالب الطبقة العامة {/*معرف الطالب*/خاص int id ؛/*اسم الطالب*/اسم السلسلة الخاصة ؛/*العلاقة بين الطلاب وفصول الدرجة الخاصة*/فصول الفصول الخاصة ؛ // حذف أساليب setter و getter}الفصول. جافا:
فصول الدرجة العامة {/*معرف الفئة*/private int id ؛/*اسم الفصل*/اسم السلسلة الخاصة ؛/*العلاقة بين الفصل والطلاب*/مجموعة خاصة <Student> الطلاب ؛ // حذف أساليب Setter و Getter}student.hbm.xml:
<؟ table = "t_student"> <id name = "id"> <generator // id> <!-خريطة الخصائص العادية-> <property name = "name"/> <!-العديد من التعيينات ، أضف مفتاحًا غريبًا إلى الطرف المتعدد-> <to to one name = "classes" column = "classid"/> </class>
classes.hbm.xml:
<؟ <class name = "classes" table = "t_classes" lazy = "false"> <id name = "id"> <generator/generator/> </id> <property name = "name"/> <!-mapplany on-to-mandy ، reverse = "true" تعني العلاقة مع الأقران-> <set name = "invorer =" </set> </class> </shibernate mapping>
فترة إعلان ذاكرة التخزين المؤقت من المستوى الأول قصير جدًا ودورة حياة الجلسة متسقة. يُطلق على ذاكرة التخزين المؤقت من المستوى الأول أيضًا ذاكرة التخزين المؤقت على مستوى الجلسة أو ذاكرة التخزين المؤقت على مستوى الشيء. ذاكرة التخزين المؤقت من المستوى الأول هي كائن ذاكرة التخزين المؤقت ولا يمكنها سمات ذاكرة التخزين المؤقت.
طريقة الاختبار (استخدم التحميل () استعلام مرتين في نفس الجلسة):
؟ System.out.println ("student.name =" + student.getName ()) ؛ /*لا يتم إصدار بيان الاستعلام ، ويستخدم التحميل ذاكرة التخزين المؤقت*/ الطالب = (الطالب) جلسة. تحميل (student.class ، 1) ؛ System.out.println ("student.name =" + student.getName ()) ؛ملاحظة: سنجد أنه عندما نستفسر لأول مرة ، سيتم وضع النتائج الموجودة في الجلسة وذاكرة التخزين المؤقت وذاكرة التخزين المؤقت من المستوى الأول. عندما أحصل على القيمة في الوقت المناسب بعد Load () في المرة الثانية ، لم أصدر عبارة للاستعلام عنها في قاعدة البيانات ، ولكن تم استرداد القيمة مباشرة من ذاكرة التخزين المؤقت (يجب أن تكون في الجلسة نفسها).
طريقة الاختبار الثانية (في نفس الجلسة):
الطالب الطالب = طالب جديد () ؛ student.setName ("Zhang San") ؛ معرف التسلسلي = session.save (الطالب) ؛ الطالب = (الطالب) session.load (student.class ، id) ؛ // لن يتم إصدار بيان الاستعلام لأن Save يدعم Cache System.out.println ("student.name =" + student.getName ()) ؛ملاحظة: يتم استدعاء طريقة SAVE () ويتم استخدام LOAD () لتحميل الكائن ، ثم يتم الحصول على سمة الاسم بالفعل ، ولكن لا يتم إصدار بيان للاستعلام عن قاعدة البيانات. لأن طريقة حفظ () تدعم أيضًا ذاكرة التخزين المؤقت.
اختبار إضافة دفعات كبيرة من البيانات:
public void testcache7 () {جلسة الجلسة = null ؛ جرب {session = hibernateutils.getSession () ؛ Session.begintransaction () ؛ لـ (int i = 0 ؛ i <100 ؛ i ++) {student student = new student () ؛ student.setName ("Zhang San" + i) ؛ Session.save (طالب) ؛ // تحديث كل 20 عنصرًا إذا (i ٪ 20 == 0) {// قم بمسح ذاكرة التخزين المؤقت ، وبعد استدعاء Flush ، سيتم حفظ البيانات في Session.flush () ؛ // مسح جلسة المحتويات المخزنة مؤقتًا. clear () ؛ }} session.getTransaction (). commice () ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ Session.getTransaction (). Rollback () ؛ } أخيرًا {hibernateUtils.Closedessesse (الجلسة) ؛ }} ملحوظة:
1. لأن طريقة Save () تدعم ذاكرة التخزين المؤقت ، هناك مشكلة. إذا أردت توفير 10 ملايين قطعة من البيانات في نفس الوقت ، فهناك 10 ملايين كائن ذاكرة التخزين المؤقت في ذاكرة التخزين المؤقت ، والتي من المحتمل أن تتسبب في تدفق. لذلك ، لا يدعم Hibernate تشغيل تحديث البيانات على نطاق واسع ، ولكن يمكننا أيضًا التعامل مع هذه المشكلة بمرونة للغاية ، مثل مسح ذاكرة التخزين المؤقت كل 20 قطعة من البيانات باستخدام حلقة.
2. حفظ ، تحديث ، SaveorupDate ، تحميل ، الحصول ، القائمة ، تكرار ، قفل سوف تضع الكائنات في ذاكرة التخزين المؤقت من المستوى الأول. لا يمكن أن تتحكم ذاكرة التخزين المؤقت من المستوى الأول في عدد ذاكرة التخزين المؤقت ، لذلك يجب عليك الانتباه إلى إمكانية تدفق الذاكرة عند تشغيل البيانات على دفعات كبيرة ؛ يمكنك استخدام طريقة Evict و Clear لمسح المحتوى في ذاكرة التخزين المؤقت.
يُطلق على ذاكرة التخزين المؤقت الثانوية أيضًا ذاكرة التخزين المؤقت على مستوى العملية أو ذاكرة التخزين المؤقت على مستوى الجلسة ، ويمكن مشاركة ذاكرة التخزين المؤقت الثانوية من قبل جميع ذاكرة التخزين المؤقت للجلسة. دورة حياة ذاكرة التخزين المؤقت الثانوية هي نفس دورة SessionFactory. يمكن لـ SessionFactory إدارة ذاكرة التخزين المؤقت الثانوية. يتم استخدام مبدأ ذاكرة التخزين المؤقت الثانوية عند القراءة أكبر بكثير من الكتابة. يتم استخدام ذاكرة التخزين المؤقت الثانوية بشكل أساسي لتخزين كائنات الكيان.
1. انسخ ملف ehcahe.xml إلى دليل SRC.
2. أضف مزود منتج ذاكرة التخزين المؤقت إلى ملف hibernate.cfg.xml ، على النحو التالي:
<name property = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </property>
3. تمكين ذاكرة التخزين المؤقت المستوى 2 (لا يمكن عرض بدء التشغيل ، لأنه يتم تمكين الافتراضي) ، على النحو التالي:
<name property = "hibernate.cache.use_second_level_cache"> true </formation>
4. حدد فئات الكيان التي تستخدم ذاكرة التخزين المؤقت من المستوى 2.
5. استيراد حزمة جرة الواجهة المستخدمة من قبل ذاكرة التخزين المؤقت: lib/optional/ehcache/ehcache-core-2.4.3.jar
محتويات ملف ehcache.xml:
<defaultCache maxElementSinMemory = "10000" eternal = "false" timetoidleSeConds = "120"
ملحوظة:
1.MaxElementSinMemory يمثل الكائنات الأكثر تخزينًا في ذاكرة التخزين المؤقت.
2. يشير TETERNAL إلى ما إذا كانت لن تنتهي صلاحيتها أبدًا (إن وضعه إلى FALSE أكثر عملية. إذا كان هذا صحيحًا ، فلن تنتهي صلاحيته أبدًا ، فإن السمات التالية لا معنى لها).
3. TimeToidLesEcods يشير إلى المدة التي لم يتم الوصول إلى الكائن بعد مرة تم مسحها.
4. تمثل TimetOlivesEcods وقت المخزون للكائن.
5. OverflowTodisk صحيح ، مما يعني أن الرقم في ذاكرة التخزين المؤقت يتجاوز الرقم المحدد بواسطة MaxElementSinMemory ويتم تخزينه على القرص.
حدد مسار القرص الذي تم حفظه على الفائض:
<diskstore path = "java.io.tmpdir"/>
ملاحظة: يمكن تغيير هذا المسار.
طريقة الاختبار (فرضية ذاكرة التخزين المؤقت من المستوى 1 هي أنه يجب أن يكون في نفس الجلسة. نستخدم الآن ذاكرة التخزين المؤقت من المستوى 2 لمعرفة ما إذا كان هناك ذاكرة التخزين المؤقت في جلستين مختلفتين):
public void testcache1 () {جلسة الجلسة = null ؛ حاول {session = hibernateUtils.getSession () ؛ session.begintransaction () ؛ طالب الطالب = (الطالب) الجلسة. {E.PrintStackTrace () ؛ session.getTransaction (). Rollback () ؛} أخيرًا {hibernateutils.closesession (session) ؛} حاول {session = hibernateutils.getSession () يمكن مشاركة البيانات في ذاكرة التخزين المؤقت الثانوية. {hibernateutils.closesession (جلسة) ؛}}ملاحظة: إذا تم تكوين ذاكرة التخزين المؤقت الثانوية ، فسنجد أنه حتى إذا تم إغلاق الجلسة الأولى ، وتم تشغيل جلسة أخرى لتحميل البيانات ، فلن تصدر عبارة للاستعلام عن البيانات في قاعدة البيانات ، لأنه يتم تكوين ذاكرة التخزين المؤقت الثانوية ، يتم مشاركتها بواسطة SessionFactory بأكملها.
تعطيل ذاكرة التخزين المؤقت من المستوى 2 لتنفيذ إضافة دفعات كبيرة من البيانات:
public void testcache5 () {جلسة الجلسة = null ؛ جرب {session = hibernateutils.getSession () ؛ Session.begintransaction () ؛ // تخزين ذاكرة التخزين المؤقت للخط الأول وتفاعل ذاكرة التخزين المؤقت الثانوية محظور Session.setCachemode (cachemode.ignore) ؛ لـ (int i = 0 ؛ i <100 ؛ i ++) {student student = new student () ؛ student.setName ("Zhang San" + i) ؛ Session.save (طالب) ؛ // تحديث كل 20 عنصرًا إذا (i ٪ 20 == 0) {session.flush () ؛ // Clear Cached Contents Session.clear () ؛ }} session.getTransaction (). commice () ؛ } catch (استثناء e) {E.PrintStackTrace () ؛ Session.getTransaction (). Rollback () ؛ } أخيرًا {hibernateUtils.Closedessesse (الجلسة) ؛ }}ملاحظة: Session.flush () تعني مسح ذاكرة التخزين المؤقت للمستوى الأول ، لكننا بدأنا ذاكرة التخزين المؤقت من المستوى الثاني مرة أخرى ، وبعد حفظ () ، فإنه يحفظه أيضًا إلى ذاكرة التخزين المؤقت من المستوى الثاني ، ولكن لا يزال هناك تدفق فائض ناتج عن ذاكرة التخزين المؤقت المفرطة. لذلك في هذه الحالة ، يجب علينا تعطيل ذاكرة التخزين المؤقت الثانوية: session.setCachemode (cachemode.ignore) ؛
ذاكرة التخزين المؤقت للاستعلام: كل من ذاكرة التخزين المؤقت من المستوى الأول وذاكرة التخزين المؤقت للتخزين المؤقت من المستوى الثاني ، كلا كلا من كيان ذاكرة التخزين المؤقت ، ولكن في بعض الأحيان نأمل في الحصول على سمات معينة ولا تصل بشكل متكرر إلى قاعدة البيانات ، ولكن الحصول عليها من ذاكرة التخزين المؤقت. في هذا الوقت ، يمكننا استخدام ذاكرة التخزين المؤقت للاستعلام. بالإضافة إلى ذلك ، سوف مجموعات نتائج ذاكرة التخزين المؤقت للاستعلام لكائنات الكيان معرف ذاكرة التخزين المؤقت. يتم تغيير دورة حياة ذاكرة التخزين المؤقت الاستعلام. عندما يتم تعديل الجدول المرتبط ، تنتهي دورة إعلان ذاكرة التخزين المؤقت للاستعلام ، والتي لا علاقة لها بدورة حياة الجلسة.
1. تعديل ملف hibernate.cfg.xml لتمكين ذاكرة التخزين المؤقت للاستعلام. إذا كان خطأ الافتراضي ، فهو غير ممكّن. يجب تعيينه على النحو التالي:
<name property = "hibernate.cache.use_query_cache"> true </splenare>
2. يجب تمكين في البرنامج ، مثل:
Query.SetCachable (صحيح)
طريقة الاختبار:
public void testcache2 () {جلسة الجلسة = null ؛ حاول {session = hibernateutils.getSsession () ؛ session.begintransactaction () (سلسلة) الأسماء. {hibernateutils.closesession (جلسة) ؛} system.out.println ("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- .list () ؛ for (int i = 0 ؛ i <names.size () ؛ i ++) {string name = (string) names.get (i) ؛ system.out.println (name) ؛} session.getTransAction (). {hibernateutils.closesession (جلسة) ؛}}ملاحظة: في الكود أعلاه ، نقوم بإيقاف تشغيل ذاكرة التخزين المؤقت الثانوية ، ونشغل ذاكرة التخزين المؤقت للاستعلام ، ثم استعن بالخصائص العادية. قم بتشغيل رمز الاختبار ويمكننا العثور على أنه في الجلسة الأولى ، يصدر الاستعلام الأول بيانًا ، ثم يغلق الجلسة ، ثم الاستعلام في الجلسة الثانية. سنجد أن الاستعلام في الجلسة الثانية لا يصدر بيانًا ، مما يعني أن ذاكرة التخزين المؤقت للاستعلام لا علاقة لها بدورة حياة الجلسة.
تكوين ذاكرة التخزين المؤقت لـ hibernate.cfg.xml:
<!-قم بتعيين واجهة التنفيذ لتحديد ذاكرة التخزين المؤقت الثانوية-> <name properن name = "net.sf.ehcache.configurationResourCename">/ehcache.xml </property> <!-قم بتعيين ذاكرة التخزين المؤقت باستخدام الاستعلام-> <property name = "hibernate.cache.use_query_cache"> true </property> Resource = "com/lixue/bean/student.hbm.xml"/> <!-ملف تعيين الموارد (أي ملف تعيين الكيان) يجب تقديمه قبل إعداد فئة كيان باستخدام ذاكرة التخزين المؤقت من المستوى 2-> <class-cache use = "end-on فقط"/>
ما ورد أعلاه هو كل محتوى هذه المقالة حول تحليل رمز أمثلة آلية ذاكرة التخزين المؤقت للإسبات ، آمل أن يكون مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!