لقد رأيت مؤخرًا النوع المخصص من السبات. لم يتعرض لها من قبل. سأقوم بتسجيله هنا كتوحيد لمعرفتي وأسمح للأصدقاء الذين لم يتعرضوا أبدًا للتعلم ودراسته معًا.
1) الأنواع المخصصة ، كما يوحي الاسم ، هي بالطبع أنواع يتم تنفيذها بنفسها لأن الأنواع الداخلية لا تلبي الاحتياجات. لا توجد العديد من هذه المواقف ، لكننا ما زلنا بحاجة إلى تعلمها. إذا كان لدينا المزيد من المهارات ، فلن نقمع جسمنا. تعلم أيضًا كيف يفكر الآخرون في كيفية التفكير في القابلية للتوسع عند إنشاء الأطر.
هناك طريقتان لتنفيذ أنواع مخصصة ، أحدهما هو تطبيق نوع المستخدم ، والآخر هو تنفيذ CompositeUserType ، وقد تكون هناك بعض الطرق ، لكنني لم أستخدمها في الوقت الحالي ، لذلك لن أتحدث عنها الآن.
أنا فقط أستخدم userType في الوقت الحالي ، دعنا أولاً نلقي نظرة على تعريف واجهة usertype:
واجهة عامة userType { /*** إرجاع رموز نوع SQL للأعمدة المعينة بواسطة هذا النوع. يتم تعريف رموز * على <tt> java.sql.types </tt>. */ public int [] sqltypes () ؛ /*** يتم إرجاع الفصل بواسطة <tt> nullsafeget () </tt>. */ الطبقة العامة returnedClass () ؛ /*** قارن حالتين من الفصل المعينة من هذا النوع من أجل الثبات "المساواة". * المساواة في الحالة المستمرة. */ منطقية عامة متساوية (الكائن X ، الكائن Y) يلقي HibernateException ؛ / ** * احصل على رمز hashcode للمثال ، بما يتوافق مع الثبات "المساواة" */ public int hashcode (Object X) يلقي HibernateException ؛ /*** استرداد مثيل للفئة المعينة من مجموعة نتائج JDBC. يجب على المنفذين * التعامل مع إمكانية القيم الخالية. */ كائن عام nullsafeget (resultset rs ، string [] أسماء ، مالك الكائن) يلقي HibernateException ، sqlexception ؛ /*** اكتب مثيلًا للفئة المعينة لبيان معد. يجب على المنفذين * التعامل مع إمكانية القيم الخالية. يجب كتابة نوع متعدد العمود * للمعلمات التي تبدأ من <TT> index </tt>. */ public void nullsafeset (reparedStatement ST ، قيمة الكائن ، مؤشر int) يرمي HibernateException ، sqlexception ؛ /** * إرجاع نسخة عميقة من الحالة المستمرة ، والتوقف في الكيانات وعلى مجموعات *. ليس من الضروري نسخ الكائنات غير القابلة للتغيير ، أو قيم * خالية ، وفي هذه الحالة يكون من الآمن إعادة الوسيطة ببساطة. */ كائن عام DeepCopy (قيمة الكائن) يلقي HibernateException ؛ /*** هل الكائنات من هذا النوع قابلة للتغيير؟ * * return boolean */ public boolean isMutable () ؛ /*** تحويل الكائن إلى تمثيله القابل للتخطيط. على الأقل يجب أن تنفيذ هذه الطريقة * نسخة عميقة إذا كان النوع قابل للتغيير. هذا قد لا يكون كافيا * لبعض التطبيقات ، ومع ذلك ؛ على سبيل المثال ، يجب أن يتم تخزين الجمعيات مؤقتًا كقيم معرف *. (عملية اختيارية) * * param قيمة الكائن ليتم تخزينه مؤقتًا * @إعادة تمثيل قابلة للتخطيط للكائن * throws hibernateException */ تفكيك التسلسل العام (قيمة الكائن) يلقي HibernateException ؛ /*** إعادة بناء كائن من التمثيل القابل للتخطيط. على الأقل يجب أن تنفيذ هذه الطريقة * نسخة عميقة إذا كان النوع قابل للتغيير. (عملية اختيارية) */ تجميع الكائن العام (Serializable Cached ، مالك الكائن) يلقي HibernateException ؛ /** * أثناء الدمج ، استبدل القيمة الحالية (الهدف) في الكيان الذي تم دمجه على * بقيمة جديدة (أصلية) من الكيان المنفصل الذي ندمجه. بالنسبة للكائنات الثابتة * ، أو القيم الفارغة ، فمن الآمن ببساطة إرجاع المعلمة الأولى. بالنسبة للكائنات القابلة للتغيير ، من الآمن إرجاع نسخة من المعلمة الأولى. بالنسبة للكائنات * مع قيم المكون ، قد يكون من المنطقي استبدال قيم المكون بشكل متكرر. */ كائن عام استبدال (الكائن الأصلي ، الهدف الكائن ، مالك الكائن) يلقي HibernateException ؛ } في الواقع ، يمكنك فهمها باللغة الإنجليزية بشكل عام ، لذلك لن أشرح ذلك أكثر. هنا ، الشيء الرئيسي الذي نحن ننفذ طريقة nullsafeset (). تستخدم هذه الطريقة بشكل أساسي حفظ هذا النوع من القيمة لقاعدة البيانات. هذه المرة سوف نتعلم كيفية استخدامه أولاً ، وبعد ذلك سندرس ببطء كيف يتم تنفيذه داخليًا.
2) الأمثلة التي كتبتها عندما كنت أدرس كانت تشير إلى مثال Xia Xin ، لذلك فهو بالتأكيد مثل معظم تلك التي تمر عبر الإنترنت. دعونا فقط نحلله تقريبًا:
فيما يلي فئة المستخدم
حزمة org.hibernate.tutorial.domain ؛ استيراد java.io.serializable ؛ استيراد java.util.list ؛ مستخدم الفئة العامة ينفذ قابلة للتسلسل {public long id ؛ اسم السلسلة الخاصة ؛ رسائل البريد الإلكتروني الخاصة بقائمة خاصة ؛ حذف طريقة الحصول على/تعيين} التالي هو فئة emaillist المخصصة:
حزمة org.hibernate.tutorial.domain ؛ استيراد java.io.serializable ؛ استيراد java.sql.preparedStatement ؛ استيراد java.sql.resultset ؛ استيراد java.sql.sqlexception ؛ استيراد java.sql.sql.types ؛ استيراد java.util.arraylist ؛ استيراد java.util.list ؛ استيراد org.hibernate.hibernate ؛ استيراد org.hibernate.hibernateException ؛ استيراد org.hibernate.usertype.usertype ؛ emaillist الفئة العامة تنفذ usertype {private static final char splitter = '؛' ؛ أنواع int final int [] private int [] new int [] {types.varchar} ؛ سلسلة خاصة (قائمة emaillist) {StringBuilder strbuf = new StringBuilder () ؛ لـ (int i = 0 ؛ i <emaillist.size () - 1 ؛ i ++) {strbuf.append (emaillist.get (i)). append (splitter) ؛ } strbuf.append (emaillist.get (emaillist.size ()-1)) ؛ إرجاع strbuf.tostring () ؛ } Private List Parse (قيمة السلسلة) {string [] strs = org.hibernate.util.stringHelper.split (value ، string.valueof (splitter)) ؛ قائمة emaillist = new ArrayList () ؛ لـ (int i = 0 ؛ i <strs.length ؛ i ++) {emaillist.add (strs [i]) ؛ } إرجاع emaillist ؛ } الكائن العام DeepCopy (قيمة الكائن) يلقي HibernateException {list sourcelist = (list) value ؛ قائمة TargetList = new ArrayList () ؛ TargetList.Add (SourceList) ؛ Return TargetList ؛ } تفكيك التسلسل العام (قيمة الكائن) يلقي HibernateException {return null ؛ } منطقية عامة تساوي (الكائن X ، الكائن Y) يلقي HibernateException {if (x == y) إرجاع True ؛ System.out.println ("X:"+x+"y:"+y) ؛ if (x! = null && y! = null) {list xList = (list) x ؛ قائمة yList = (list) y ؛ if (xlist.size ()! = ylist.size ()) إرجاع false ؛ لـ (int i = 0 ؛ i <xlist.size () ؛ i ++) {string str1 = (string) xList.get (i) ؛ String str2 = (String) yList.get (i) ؛ if (! str1.equals (str2)) إرجاع خطأ ؛ } إعادة صواب ؛ } إرجاع خطأ ؛ } boolean public isMutable () {return false ؛ } الكائن العام nullsafeget (resultset rs ، string [] أسماء ، مالك الكائن) يلقي HibernateException ، sqlexception {string value = (string) hibernate.string.nullsafeget (rs ، names [0]) ؛ if (value! = null) {return parse (value) ؛ // paste list ؛ تقسيم} آخر {return null ؛ }} public void nullsafeset (reparedStatement ST ، قيمة الكائن ، int index) يلقي HibernateException ، sqlexception {system.out.println ("Set Methoded!") ؛ System.out.println ("القيمة:" + قيمة) ؛ if (value! = null) {string str = compleble ((list) value) ؛ // استخدم السلاسل ؛ splice hibernate.string.nullsafeset (ST ، STR ، INDEX) ؛ } آخر {hibernate.string.nullsafeset (ST ، value ، index) ؛ }} الفئة العامة returnedClass () {return list.class ؛ } public int [] sqltypes () {return types ؛ } // حذف الطرق الأخرى التي لا تتطلب التعديل} الأساليب التي تم تنفيذها في الفصل هي الأساليب التي تحتاج إلى تعديل ، والأساليب الأخرى التي لا تحتاج إلى تعديلها في الوقت الحالي لم يتم كتابتها ، لكنها لا تزال بحاجة إلى تنفيذها.
3) التالي هو ملف تعيين فئة المستخدم:
<class name = "user" table = "user"> <id name = "id" column = "user_id" type = "java.lang.long"> <generator/> </id> <property name = "name" type = "string" COMPUMENT = "user_name"/> <property name = "elemt
أعتقد أن الجميع يعرف كيفية تعديله ، ولن أشرح ذلك هنا. إنه يغير بشكل أساسي نوع رسائل البريد الإلكتروني ويغيرها إلى فئة emaillist التي حددناها للتو.
4) أخيرًا ، دعنا نكتب فئة اختبار:
استيراد java.util.hashmap ؛ استيراد java.util.list ؛ استيراد java.util.map ؛ استيراد java.util.arraylist ؛ استيراد junit.framework.testcase ؛ استيراد org.hibernate.entityMode ؛ استيراد org.hibernate.session ؛ استيراد org.hibernate.SessionFactory ؛ استيراد org.hibernate.transaction ؛ استيراد org.hibernate.cfg.configuration ؛ استيراد org.hibernate.tutorial.domain.user ؛ الطبقة العامة hibernatetest يمتد testcase {جلسة خاصة = null ؛ إعداد void المحمي () يلقي استثناء {التكوين cfg = جديد التكوين (). configure () ؛ SessionFactory SessionFactory = cfg.buildSessionFactory () ؛ الجلسة = sessionfactory.opensession () ؛ } public void testinsert () {Transaction Tran = null ؛ حاول {tran = session.begintransaction () ؛ مستخدم المستخدم = مستخدم جديد () ؛ user.setName ("Shun") ؛ قائمة قائمة = ArrayList () جديد ؛ list.add ("[email protected]") ؛ list.add ("[email protected]") ؛ user.setemails (قائمة) ؛ Session.save (user) ؛ tran.Commit () ؛ } catch (استثناء ex) {ex.printStackTrace () ؛ if (tran! = null) {tran.rollback () ؛ }} محمي باطل kushdown () يلقي الاستثناء {session.close () ؛ }} قد تكون هناك مشكلة هنا. عندما نقوم بحفظ بريد إلكتروني واحد فقط ، سيكون لها استثناء. حقل البريد الإلكتروني في قاعدة البيانات فارغ. عندما يكون لدينا رمزان مثل الرمز أعلاه ، لن تكون هناك مشكلة. النتيجة في قاعدة البيانات كما هو موضح في الشكل:
وعندما نوفر واحدًا فقط ، يكون الاستثناء كما يلي:
java.lang.classcastexception: java.util.arraylist لا يمكن إلقاؤها إلى java.lang.string
يحدث في طريقة متساوية من emaillist ، String str1 = (String) Xlist.get (i) ؛ في هذا الرمز ، بعد التحقق ، يصبح قائمة قائمة عند إدخال البيانات ونقلها إلى طريقة Nullsafeset الخاصة بـ Emaillist ، وهي ،
القيمة: [[[email protected] ، [email protected]]]] سيؤدي هذا النموذج إلى حدوث مشاكل عند المقارنة. لها دائمًا قيمة واحدة فقط ، لكنها مختلفة عند المقارنة.
if (xlist.size ()! = ylist.size ()) إرجاع false ؛
لذلك ستكون هناك مشاكل عند الصب.
بعد التفتيش ، طريقة متساوية:
X: [[[email protected] ، [email protected]]] y: [[email protected] ، [email protected]]
هذه النتيجة غريبة جدا. لم يتحدث الإنترنت عن سبب حدوث هذا الموقف. اسمحوا لي أن أقترحها هنا: إصدار السبات الذي أستخدمه هو Hibernate 3.3.2.ga. لا أعرف ما إذا كانت مشكلة الإصدار أو مشكلة أخرى ، فلندرسها غدًا. إذا كان أي شخص يعرف السبب ، آمل أن أخبرني.