English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
هذا المقال جمع خمس طرق لحل مشكلة التحميل التلقائي في Hibernate التي واجهتها خلال دراستي.
يُطلق على التحميل التلقائي (lazy) التحميل المتأخر، التحميل المتأخير.
متى نستخدم التحميل التلقائي؟ يمكنني أن أجيب فقط أن نستخدم التحميل التلقائي عندما نحتاج إلى ذلك.
إذن لماذا نستخدم التحميل التلقائي؟ لأنه عندما يكون حجم البيانات الذي نريد الوصول إليه كبيرًا، فإن استخدام المخزن المؤقت ليس مناسبًا، لأن حجم الذاكرة محدود. من أجل تقليل عدد التفاعلات المتوازية، وتقليل استهلاك موارد النظام، نحن نحمّل البيانات عند الحاجة، ونستخدم في هذه الحالة التحميل التلقائي.
على سبيل المثال، هناك كائن هو Employee، هناك كائن آخر هو Department. من الواضح، بالنسبة لكائن Employee بالنسبة لكائن Department، هناك علاقة متعددة إلى واحدة؛ بينما بالنسبة لكائن Department بالنسبة لكائن Employee، هناك علاقة واحدة إلى متعددة. عندما نبحث عن كائن Employee، إذا كنا نريد أن نصل إلى كائن Department الخاص بكائن employee عن طريق خاصية department، فإنه سيكون هناك استثناء. هذا بسبب وجود التحميل التلقائي، بعد إغلاق الجلسة، يرسل Hibernate طلبًا إلى قاعدة البيانات مرة أخرى، مما يؤدي إلى رفع استثناء.
إليك تلخيص لـ أربعة طرق لحل هذه المشكلة:
1. التحميل الموضعي (داخل طريقة الاستعلام)
عندما تريد استعلام أي موظف ينتمي إلى أي قسم، يجب إجراء استعلام مسبق لـ Department
استخدام جملة
Hibernate.initialize(Department.class);
2. تعديل ملف العلاقات بين الأجراء، وتحويل lazy إلى lazy=false، أي إغلاق التحميل التلقائي
بالطبع، يمكن لهذه الطريقتين حل المشكلة، ولكن العيب في ذلك هو أن Hibernate سيرسل دائمًا أوامر SQL إلى قاعدة البيانات للحصول على البيانات، مما يؤدي إلى إهدار غير ضروري للقدرة على الأداء.
3. استخدام الملفتر (مشروع الويب)
① يجب استخدام getCurrentSession للحصول على session
② طريقة إغلاق session خاصة
public void doFilter(ServletRequest request, ServletResponse response, FilterChain arg2) throws IOException, ServletException { // TODO stub تم إنشاؤه تلقائيًا Session session = null; Transaction tx = null; try { session = HibernateUtil.getCurrentSession(); tx = session.beginTransaction(); arg2.doFilter(request, response);// يستمر الطلب في الحركة tx.commit(); } catch (Exception e) { // TODO: معالجة الاستثناء if(tx != null){ tx.rollback(); } }finally{ // طريقة إغلاق خاصة HibernateUtil.closeCurrentSession(); } }
4. في إطار SSH، يتم استخدام openSessionView التي يقدمها Spring
مبدأه مشابه للطريقة الثالثة التي تستخدم Filter، ولكن هذا الفلتر هو مقدم من Spring. عند الاستخدام، يجب إعداد web.xml كما يلي:
<!-- حل مشكلة التحميل التأخري باستخدام Spring --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
يمكن حل مشكلة التحميل التأخري أيضًا بالطرق الثالثة والرابعة، والطريقة الرابعة هي أيضًا الطريقة التي يتم استخدامها بشكل متكرر حاليًا. ولكن لديهما أيضًا عيوب، والعيب الرئيسي هو تمديد وقت إغلاق الجلسة، مما يطيل دورة حياة الجلسة. قبل استخدام هذه الطريقة، يتم إغلاق الجلسة بعد استعلام البيانات؛ الآن، يتم إغلاق الجلسة في نهاية الطلب الويب.
الخلاصة
هذا هو محتوى المقال الكامل حول مناقشة 4 طرق لتحلل مشكلة التحميل التأخري لـ Hibernate، آمل أن يكون مفيدًا لكم. يمكن للزوار المهتمين متابعة مواضيع أخرى ذات صلة بالموقع، وترحيبًا بالتعليقات التي تشير إلى نقاط الضعف. شكرًا للدعم الذي يقدمونه للواقع!
البيان: محتوى هذا المقال تم جمعه من الإنترنت، يحق لصاحب الحقوق الحصول عليه، تم جمع المحتوى من قبل المستخدمين على الإنترنت وتم تحميله بشكل تلقائي، هذا الموقع لا يملك حقوق الملكية، لم يتم تعديل المحتوى بشكل يدوي، ولا يتحمل هذا الموقع أي مسؤولية قانونية. إذا كنت قد وجدت محتوى يشتبه في انتهاك حقوق النسخ، فلا تتردد في إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال '#' بـ '@') لإبلاغنا، وقدم الدليل على الدليل، إذا تم التحقق من ذلك، سيتم حذف المحتوى المزعوم بسرعة.