اعتراض
عند الحديث عن اعتراض ، أعتقد أن أحذية الأطفال المألوفة بـ Struts2 على دراية بالتأكيد بـ Struts2. يمكن لـ Struts2 تخصيص المعترض لأداء سلسلة من الأعمال ذات الصلة التي تريدها. والاعتراض الذي نتحدث عنه هنا له وظائف مماثلة.
دون أن يقول هراء ، فقط رمز:
فيما يلي فئة MyInterceptor ، التي تنفذ واجهة التقاطع:
السلسلة العامة OnPreparestatement (String arg0) {return arg0 ؛ } public boolean onsave (Object Arg0 ، arg1 serializable ، object [] arg2 ، string [] arg3 ، type [] arg4) يلقي callbackexception {if (arg0 attleof user) {system.out.println ("user to stave =>"+(user) arg0) .getName ()) ؛ } إرجاع خطأ ؛ } لن أقرأ طرقًا أخرى ، فقط اتبع التنفيذ الافتراضي. نحتاج فقط إلى تغيير هاتين الطريقتين. نحتاج إلى تغيير قيمة الإرجاع في Onpreparestatement لإرجاع بيان SQL الحالي. المعلمات هي عبارة SQL التي تم تنفيذها. يمكننا طباعة البيان عن طريق إرجاعه مباشرة.
في onSave ، يمكنك معرفة أنه يسمى عند الادخار. يمكننا القيام بسلسلة من أعمال ما قبل الحفاظ عليها.
أعتقد أن الجميع يمكنهم فهمه من خلال النظر إلى أسماء المعلمات.
يشير Serializable إلى معلمة رقم التسلسل ، والتي تشير إلى السمات التي تخطط لمعرف قاعدة البيانات.
الكائن [] هذه سلسلة من الحالات ، والتي لم يتم استخدامها كثيرًا في الوقت الحالي. سأدرسها لاحقًا. ومع ذلك ، يوضح واجهة برمجة التطبيقات أنه بغض النظر عن كيفية تعديل القيمة في هذه الصفيف ، يجب أن تعود طريقة OnSave بشكل صحيح.
تشير String [] إلى اسم السمة والنوع [] هو نوع السمة المقابلة.
1) يمكن لهذا الاعتراض القيام ببعض العمليات المقابلة قبل وبعد حفظ قاعدة البيانات. على سبيل المثال ، إذا كنت ترغب في تعديل البيانات وإضافة بادئة أو لاحقة ، فيمكنك استخدامها لتنفيذها. دعونا نلقي نظرة عليه أدناه.
onsave المنطقية العامة (كائن Arg0 ، Arg1 القابل للتسلسل ، الكائن [] Arg2 ، String [] Arg3 ، type [] arg4) يلقي callbackexception {if (arg0 atter user) {system.out.println ("user sove =>"+(user) arg0) .getName ()) ؛ } // نضيف 123 كبادئة للاسم هنا المستخدم = (المستخدم) Arg0 ؛ user.setName ("123"+user.getName ()) ؛ العودة كاذبة }لنلقي نظرة على طريقة الاختبار:
public static void main (string [] args) {configuration cfg = new configuration (). configure () ؛ SessionFactory SessionFactory = cfg.buildSessionFactory () ؛ اعتراض اعتراض = جديد myinteceptor () ؛ جلسة الجلسة = sessionfactory.opensession (اعتراض) ؛ مستخدم المستخدم = مستخدم جديد () ؛ user.setName ("Shun") ؛ المعاملة tx = session.begintransaction () ؛ Session.save (user) ؛ tx.Commit () ؛ session.close () ؛ } الأمر بسيط للغاية ، لقد أنقذناها ببساطة. لا توجد ملفات رسم الخرائط وفئات الكيانات هنا ، فقط جربها.
قم بتشغيله ويمكننا أن نرى:
يجب حفظ المستخدم => shun hibernate: أدخل في قيم المستخدم (user_name ، العمر) (؟ ،؟) hibernate: تحديث المستخدم user_name =؟ ، العمر =؟ أين user_id =؟سيقوم بتحديث الاسم والعمر في النهاية ، وذلك أساسًا لأننا أجرينا تغييرات في طريقة OnSave.
onload boolean العامة (الكائن Arg0 ، Arg1 القابل للتسلسل ، الكائن [] Arg2 ، String [] arg3 ، type [] arg4) يلقي callbackexception {if (arg0 atter user) {system.out.println ("المستخدم المراد تحميله =>"+(Arg2 [0]+":"+arg2 [1])) ؛ } مستخدم المستخدم = (المستخدم) arg0 ؛ . Arg2 [i] = ((سلسلة) arg2 [i]). استبدال ("123" ، "") ؛ }} إرجاع خطأ ؛ } قيمة السمة المعدلة عند كتابة التحميل في طريقة ONLOAD.
Arg0 هنا هو كائن المستخدم لدينا. ليس لها قيمة بعد. يتم استدعاء هذه الطريقة بعد طريقة التحميل ، لذلك من غير المجدي بالنسبة لنا تشغيل المستخدم في هذا الوقت ، و user.setName هنا عملية عديمة الفائدة. أساسا في:
Arg2 [i] = ((سلسلة) arg2 [i]). استبدال ("123" ، "") ؛
يغير هذا الرمز قيمة السمة التي تم إرجاعها ، وبالتالي فإن القيمة في كائن المستخدم الذي نحصل عليه في البرنامج ستتغير أيضًا. دعنا ندير طريقة الاختبار لمعرفة:
public static void main (string [] args) {configuration cfg = new configuration (). configure () ؛ SessionFactory SessionFactory = cfg.buildSessionFactory () ؛ اعتراض اعتراض = جديد myinteceptor () ؛ جلسة الجلسة = sessionfactory.opensession (اعتراض) ؛ مستخدم المستخدم = (المستخدم) Session.load (user.class ، New Long (39)) ؛ System.out.println ("اسم المستخدم:"+user.getName ()) ؛ session.close () ؛ }بالنظر إلى النتائج ، حصلنا على:
hibernate: حدد user0_.user_id as user1_0_0_ ، user0_ يجب تحميل المستخدم => 123shun: 0 اسم المستخدم: Shun
لقد أزلنا 123 الأصلي وقمنا بإجراء المعالجة ذات الصلة بعد التحميل الفعلي ، ولكن هذه ليست معالجة حقيقية قبل التحميل الفعلي ، وهي مشبوهة بعض الشيء من المضاربة. لكنه أيضا اعتبار. يمكن استخدام اعتراض أكثر في المعالجة ذات الصلة للسجلات. على سبيل المثال ، نحتاج إلى تسجيل المقابل لكل عملية ، لذلك يعتبر Interceptor اختيارًا جيدًا.
مجموعة
هل تتذكر المجموعة التي استخدمناها في أحد الأمثلة السابقة ، هل ما زلت لديك الانطباع؟ إذا لم تقم بذلك ، فابحث عن المعلومات ومراجعتها. اليوم سوف نتعلم حول هذه المجموعات.
دعنا نصل فقط إلى هذه النقطة.
1) أولاً دعنا نتعلم مجموعة. يعلم الجميع أن هناك أيضًا مجموعة في حزمة Java Util. إذن ما هو الفرق والاتصال بين المجموعة والمجموعة في السبات؟ نفتح واجهة برمجة تطبيقات Hibernate ، ونجد مجموعة ، ويمكنك رؤيتها.
ما نراه هو فئة الوالدين لمجموعة السبات هذه. إنها فئة مجردة مع سلسلة من فئات التنفيذ الملموسة. عندما نستمر في رؤية الطريقة التالية ، نجد أن هذه الفئة تنفذ تغليف مجموعة Java ، لذلك نفهم أن مجموعة السبات المزعومة لا تتغلف إلا في مجموعة Java.
لذلك ، هل هذه الخاصية لا تسمح عناصر مكررة في المجموعة أيضًا في السبات؟ الجواب بالطبع نعم.
نحن لا ننظر إلى هذه هنا. في الماضي ، عندما تعلمنا رسم الخرائط ، ارتبطنا مباشرة الخصائص مع الفئات المرتبطة ، لكننا اليوم لسنا هكذا. نستخدم طريقة أخرى ، فقط ربط سلسلة لمعرفة ما إذا كانت هناك أي مشكلة.
ولكن قبل النظر في هذا السؤال ، دعونا نلقي نظرة على مقارنة السلسلة في Java.
ما نراه هو فئة الوالدين لمجموعة السبات هذه. إنها فئة مجردة مع سلسلة من فئات التنفيذ الملموسة. عندما نستمر في رؤية الطريقة التالية ، نجد أن هذه الفئة تنفذ تغليف مجموعة Java ، لذلك نفهم أن مجموعة السبات المزعومة لا تتغلف إلا في مجموعة Java.
لذلك ، هل هذه الخاصية لا تسمح عناصر مكررة في المجموعة أيضًا في السبات؟ الجواب بالطبع نعم.
نحن لا ننظر إلى هذه هنا. في الماضي ، عندما تعلمنا رسم الخرائط ، ارتبطنا مباشرة الخصائص مع الفئات المرتبطة ، لكننا اليوم لسنا هكذا. نستخدم طريقة أخرى ، فقط ربط سلسلة لمعرفة ما إذا كانت هناك أي مشكلة.
ولكن قبل النظر في هذا السؤال ، دعونا نلقي نظرة على مقارنة السلسلة في Java.
public static void main (string [] args) {string s1 = "shun1" ؛ السلسلة S2 = "Shun1" ؛ System.out.println ("S1 == S2:"+(S1 == S2)) ؛ } أعتقد أن العديد من أحذية الأطفال يعرفون أن الإجابة صحيحة.
قبل تقديم مثال ، دعونا نلقي نظرة على ملف التعيين الخاص بنا. لن نكتب فصول التعيين:
هذا هو ملف تعيين Tuser:
<class name = "tuser" table = "t_user" dynamic-insert = "true" dynamic-update = "true" dynamic-update = "true"> <id name = "id" id " column = "Age"/> <set name = "address" cascade = "all" table = "t_address"> <key column = "user_id"/> <!-<One-to-many/>-> <element colump
التالي هو ملف تعيين العنوان:
<class name = "address" table = "t_address" dynamic-insert = "false" dynamic-update = "false"> <id name = "id" column = "id" type = "java.lang.integer not-null = "true"> </any to one> </splass>
لقد رأى حذاء الأطفال ذلك بوضوح. لقد علقت من شخص واحد في المجموعة في Tuser وعنصر المستخدم. بغض النظر عن المشكلة ، دعونا ننظر إلى قاعدة البيانات أولاً:
هذا هو جدول T_Address:
هنا جدول T_USER:
يمكننا أن نرى أن المستخدم مع المعرف 4 يتوافق مع ثلاثة عناوين. بعد ذلك ، دعونا نلقي نظرة على طريقة الاختبار:
public static void main (string [] args) {configuration cfg = new configuration (). configure () ؛ SessionFactory SessionFactory = cfg.buildSessionFactory () ؛ جلسة الجلسة = sessionfactory.opensession () ؛ tuser user = (tuser) session.load (tuser.class ، integer (4)) ؛ set set = user.getAdDresses () ؛ session.close () ؛ System.out.println ("حجم العنوان:"+set.size ()) ؛ } فئة استعلام بسيطة للغاية ، فقط أخرجت هذه النتيجة ، رأينا ظاهرة غريبة:
حجم العنوان: 1
هذه هي النتيجة!
ستقول بالتأكيد ، يجب أن يكون خطأ ، إنه خطأ في السبات. يجب أن أكون سعيدًا هنا. يمكنني أخيرًا إرسال خطأ. عندما قمت بتبديل الوظائف ، يمكنني أن أقول بصوت عالٍ أنني قدمت خطأً في السبات. هاها ، ولكن لسوء الحظ ، هذا ليس خطأ.
قلت للتو إن المقارنة بين السلسلة التي كانت لدينا أمامها كانت تمهد الطريق هنا ، فكيف تمهدها؟
نستخدم تعيين في ملف التكوين وربطه من خلال أحرف السلسلة. ثم ، عندما يتم إخراجها في قاعدة البيانات ووضعها في المجموعة ، ستحدد أولاً ما إذا كانت قيم الحرف المرتبطة متساوية. هنا ، نظرًا لأن قيمنا متساوية (لن نحفر في كيفية مقارنتها في الوقت الحالي) ، نحتاج فقط إلى معرفة أنه عندما نستخدم السلاسل للمقارنة ، فإننا نقع في فخ السلسلة في Java مرة أخرى. إذا اكتشفت أن هناك واحدة فقط ، فإن الحذف يكون أكثر إزعاجًا عند حذفه ، فسيحذف جميع السجلات نفسها.
ثم دعونا نلقي نظرة على واحدة محذوفة:
tuser user = (tuser) session.load (tuser.class ، integer (4)) ؛ المعاملة tx = session.begintransaction () ؛ Object obj = user.getAdDresses (). iterator (). next () ؛ user.getAddresses (). إزالة (OBJ) ؛ tx.Commit () ؛ session.close () ؛
إخراج البيان من قبل السبات هنا هو:
Hibernate: حذف من t_address حيث user_id =؟
أعتقد أن الجميع يعرف متى يحذف جميع العناوين تحت المستخدم. لا يوجد خيار سوى حذف كل هذا.
لذلك تحتاج إلى الانتباه إليها في تطور حقيقي.
2) تحدثنا عن المجموعة أعلاه ، ويبدو أنه ليس من الجيد الاستخدام. هناك مثل هذا الفخ ، ولكن لا توجد طريقة. SET هي تلك التي نستخدمها أكثر من غيرها ، وعموما لن يربط أحد الأوتار مباشرة. لكن الكثير من الناس ما زالوا غير راضين ، لذلك سيكون لدى السبات حقيبة إضافية كما هو مطلوب (ربما ليس كما هو مطلوب ، ربما يكون بعض الأشخاص فيها غير راضين ، هاها).
دعونا نلقي نظرة أولاً على استخدامه الأساسي:
أولاً ، نحتاج إلى تعديل علامة تعيين في ملف تعيين Tuser السابق إلى:
<bag name = "addresses" lazy = "true" table = "t_address"> <key column = "user_id" /> <element type = "string"
ويحتاج فئة الكيان المقابلة إلى تعديل نوع العناوين لنوع القائمة.
هنا نضيف ثلاثة عناوين:
ندير رمز الاختبار:
public static void main (string [] args) {configuration cfg = new configuration (). configure () ؛ SessionFactory SessionFactory = cfg.buildSessionFactory () ؛ جلسة الجلسة = sessionfactory.opensession () ؛ tuser user = (tuser) session.load (tuser.class ، integer (4)) ؛ System.out.println ("حجم العنوان:"+user.getAddresses (). size ()) ؛ session.close () ؛ }
هنا نرى:
حجم العنوان: 3
هذه المرة يمكننا أن نرى كل شيء ، بغض النظر عما إذا كانت هناك أي تكرار أم لا.
لكننا نظرنا فقط إلى مشكلة الحذف. لم يتم حل الحقيبة هنا ، ونحن بحاجة إلى استخدام IDBAG. نرى ملف التكوين ونحتاج إلى التعديلات التالية:
idbag name = "addresses" table = "t_address" lazy = "true"> <collection-id type = "int" column = "id"> < /> /collection-id> <key colun
نرى أنه يحتوي على معرف تجميع واحد فقط من الحقيبة للإشارة إلى رقم السجل الذي سيتم حذفه.
عندما نعيد تشغيل الرمز المحذوف:
tuser user = (tuser) session.load (tuser.class ، integer (4)) ؛ المعاملة tx = session.begintransaction () ؛ Object obj = user.getAdDresses (). iterator (). next () ؛ user.getAddresses (). إزالة (OBJ) ؛ tx.Commit () ؛
نرى أن بيان الإخراج هو:
السبات: حذف من t_address أين المعرف =؟
هذه المرة ، لا يتم حذفها من خلال user_id ، ولكن بناءً على معرف T_Address ، مما يعني أنه يحذف السجل الذي نحتاجه حقًا.
نرى قاعدة البيانات والسجل الآن:
لقد حذفنا السجل الأول ، فهو صحيح.
3) بعد النظر إلى الطريقتين أعلاه ، دعنا نلقي نظرة على الخريطة. الفرق الأكبر بينه وبين الاثنين أعلاه هو أنه يمكن أن يتوافق مع القيم الرئيسية. انظر مباشرة إلى الكود ، وجهة النظر البديهية:
أولاً ، نحتاج إلى تعديل ملف التكوين:
<map name = "addresses" table = "t_address" lazy = "true"> <key column = "user_id" /> <index type = "String"
الفرق الأكبر بينها وبين الاثنين السابق هو أن هناك فهرس ، وهو ما يعادل مفتاح الخريطة في Java ، ونحن نستخدم هذا لاسترداد السجلات المقابلة. تذكر ، بعد التغيير هنا ، تحتاج إلى تغيير فئة الكيان المقابلة ، وتحتاج إلى تغيير نوع سمة العناوين إلى الخريطة.
انظر إلى بيانات قاعدة البيانات:
هنا نرى أن هناك مكتبان ومنزل واحد ، إذن أي مكتب يجب استخدامه؟
لا تقلق ، سنعرف بعد تشغيل رمز الاختبار:
tuser user = (tuser) session.load (tuser.class ، integer (4)) ؛ System.out.println (user.getAddresses (). get ("home")) ؛ System.out.println (user.getAddresses (). get ("Office")) ؛شانوي شنغهاي
نعم ، كما يوضح النتيجة ، فإننا نتخلف عن ذلك ، وهو نفس مبدأ الخريطة. ستعمل القيم المخزنة على الكتابة فوق القيم السابقة (إذا كانت نفس المفتاح).
الخريطة بسيطة نسبيا ، والتي تشبه الأولين.
4) دعونا نلقي نظرة على آخر واحد. القائمة مختلفة عن تلك السابقة ، ويمكن فرزها.
دعونا نلقي نظرة على كيفية تنفيذها:
أولاً ، دعنا نعدل ملف التعيين:
<list name = "addresses" table = "t_address" lazy = "true"> <key column = "user_id" /> <indexty = "string"
يشبه تكوين الخريطة ، ولكن سمات الفهرس مختلفة. يتم استخدام الفهرس في الخريطة كمفتاح للحصول على القيمة ، بينما يتم استخدام فهرس القائمة كفرز.
دعونا نلقي نظرة على قاعدة البيانات:
قمنا بتعيين ثلاث قيم بترتيب 0 و 1 و 2.
دعنا ندير الرمز لتغيير قيم 0 و 2:
tuser user = (tuser) session.load (tuser.class ، integer (4)) ؛ المعاملة tx = session.begintransaction () ؛ Object OBJ1 = user.getAddresses (). get (0) ؛ Object OBJ2 = user.getAddresses (). get (2) ؛ user.getAddresses (). set (0 ، obj2) ؛ user.getAddresses (). set (2 ، obj1) ؛ tx.Commit () ؛
نرى النتائج:
نرى أنه تم استبدال 0 و 2 ، وبالطبع هذا هو مجرد تغيير قيمة IDX. ولكن هذا قد نفذ أساسا وظيفة الفرز.