البحث الرئيسي في هذه المقالة هو المحتوى ذي الصلة لاستعلام HQL HQL ، على النحو التالي.
لغة الاستعلام Hibernate (HQL) عبارة عن بيان استعلام موجه بالكامل مع وظائف استعلام قوية للغاية ؛ لديها تعدد الأشكال والارتباط والخصائص الأخرى. استعلام HQL هو أيضًا طريقة الاستعلام الموصى بها رسميًا من قبل Hibernate.
بعد ذلك ، نقوم بتحليل طرق الاستعلام ذات الصلة من خلال دراسة حالة
الفصول. جافا:
فصول الدرجة العامة {/*معرف الفئة*/private int id ؛/*اسم الفصل*/اسم السلسلة الخاصة ؛/*العلاقة بين الفصل والطلاب*/مجموعة خاصة <Student> الطلاب ؛ // حذف أساليب Setter و Getter}student.java:
طالب الطبقة العامة {/*معرف الطالب*/خاص int id ؛/*اسم الطالب*/اسم السلسلة الخاصة ؛/*العلاقة بين الطلاب وفصول الدرجة الخاصة*/فصول الفصول الخاصة ؛ // حذف أساليب setter و getter}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>
student.hbm.xml:
<؟ table = "t_student"> <id name = "id"> <generator // id> <!-خريطة الخصائص العادية-> <property name = "name"/> <!-العديد من التعيينات ، أضف مفتاحًا غريبًا إلى الطرف المتعدد-> <to to one name = "classes" column = "classid"/> </class>
/*إرجاع قائمة سمة SET SET ، ونوع العنصر ونوع السمات في فئة الكيان هي نفسها*/ LIST <TRING> students = session.createquery ("حدد اسم الطالب"). LIST () ؛ /*travel*/ for (iterator <string> iter = student.iterator () ؛ iter.hasNext () ؛) {string name = (string) iter.next () ؛ system.out.println (name) ؛ }ملاحظة: عند الاستعلام عن سمة واحدة ، تكون المجموعة التي تم إرجاعها عبارة عن مجموعة ، ونوع عنصر المجموعة هو نوع السمة.
/*الاستعلام عن خصائص متعددة ، إرجاع مجموعة كائن*/ قائمة <Object []> students = session.createquery ("حدد المعرف ، الاسم من الطالب"). list () ؛ /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: استعادة سمات متعددة إرجاع مجموعة من صفائف كائنات النوع. هذا سهل الفهم. عند الاستعلام عن سمة واحدة ، يكون نوع عنصر المجموعة الذي تم إرجاعه ، فهو نوع السمة ، ولكن ماذا عن أنواع متعددة؟ يجب أن يكون هذا صفيف كائن للمعالجة ، أي الكائن [].
/*قمنا بتعيين المُنشئ المقابل لكائن الكيان ، ثم يمكننا إرجاع مجموعة من أنواع كائنات الكيان عن طريق الاستعلام عن كائن*/ قائمة الطلاب = session.createquery ("حدد طالب جديد (معرف ، اسم) من الطالب"). القائمة () ؛ /*travel*/ for (iterator iter = students.iterator () ؛ iter.hasnext () ؛) {student student = (student) iter.next () ؛ System.out.println (student.getId () + "،" + student.getName ()) ؛ }ملاحظة: بالإضافة إلى الطريقة الثانية ، نعيد صفيف كائن ، يمكننا أيضًا تعيين المُنشئ المقابل لكائن الكيان ، ثم الاستعلام عن الكائن عن طريق الاستعلام عن الكائن ، ثم إرجاع مجموعة من أنواع الكيانات.
/*يمكن استخدام الأسماء المستعارة*/ LIST <Object []> students = session.createquery ("Select S.ID ، S.Name from student s"). list () ؛ /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ } . /*transip*/ for (iterator <Tudent> iter = student.iterator () ؛ iter.hasNext () ؛) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ }ملاحظة: يمكن لكيانات الاستعلام استخدام شكل من اسم الفصل مباشرة.
/*استخدم SELECT لاستخدام الاسم المستعار*/ LIST <Tudtude> students = session.createquery ("SELECT S من الطالب S"). list () ؛ /*transip*/ for (iterator <Tudent> iter = student.iterator () ؛ iter.hasNext () ؛) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ }ملاحظة: إذا كنت ترغب في استخدام الكلمة الرئيسية SELECT ، فيجب عليك استخدام الاسم المستعار. يجب ملاحظة نقطة أخرى: HQL لا يدعم شكل SELECT *.
/ ** * إذا كنت تستخدم قائمة للاستعلام عن كائن الكيان ، فسيتم إصدار عبارة استعلام للحصول على بيانات كائن الكيان * * hibernate: حدد student0_.id as id0_ ، student0_.name as name0_ ، الطالب "). قائمة () ؛ /*travel*/ for (iterator <Tudent> iter = student.iterator () ؛ iter.hasNext () ؛) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ }ملاحظة: عند استخدام طريقة .list () للاستعلام عن الكائنات ، سيتم إصدار عبارة واحدة فقط ، أي عبارة تحصل على بيانات الكائن الفعلي.
/*** ستحدث مشكلة N+1. يشير ما يسمى بـ N+1 إلى إصدار بيانات N+1 SQL * * 1: إصدار عبارة تكرس قائمة المعرف * hibernate: حدد student0_.id as col_0_0_ من t_student student0_ * * n: إصدار بيانات n sql استنادًا إلى المعرف لتحميل الكائن ذي الصلة * hibernate: * student0_.createTime as createTime0_0_ ، student0_.classesid as classIsID0_0_ * from t_student student0_ where student0_.id =؟ * */ iterator <Tudent> iter = session.createquery ("من الطالب"). iTerAte () ؛ /*travel*/ while (iter.hasnext ()) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ }ملاحظة: عند إجراء استعلام الكائن من خلال ITerator () ، سيتم إصدار بيانات N+1. أولاً ، سيتم إصدار بيان للاستعلام عن معرف كائن الكيان ، ثم سيتم إصدار عبارات n بناءً على معرفاتها الخاصة بالاستعلام عن كائنات n. الأداء الرسمي ضعيف نسبيا.
/*تخزين مجموعة الاستعلام في ذاكرة التخزين المؤقت من المستوى الأول ، أي ذاكرة التخزين المؤقت على مستوى الجلسة*/ LIST <Tudtude> students = session.createquery ("من الطالب"). القائمة () ؛ /*transip*/ for (iterator <Tudent> iter = student.iterator () ؛ iter.hasNext () ؛) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ } System.out.println ("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- يتم وضع البيانات في القائمة ، سيتم وضع البيانات في ذاكرة التخزين المؤقت للجلسة (ذاكرة التخزين المؤقت من المستوى الأول) ، عند استخدام التكرار ، * أولاً ، سيتم إصدار عبارة عن قائمة معرفات ، ثم سيتم تحميل البيانات المقابلة في ذاكرة التخزين المؤقتة وفقًا للمعرف إذا كانت هناك بيانات تتوافق معها. ذاكرة التخزين المؤقت ، يمكن أن تحسن الأداء ، وإلاملاحظة: في الواقع ، يوفر Hibernate استعلام Iterator () لتحسين الأداء ، فلماذا يساعد كثيرًا؟ والسبب هو أن ITerator () يجلب البيانات من ذاكرة التخزين المؤقت من المستوى الأول. إذا كانت هناك بيانات في ذاكرة التخزين المؤقت ، فإن كفاءتها ستكون بلا شك قوية للغاية. ومع ذلك ، عندما أستفسر عن المرة الأولى ، كيف يمكن أن تكون هناك بيانات في ذاكرة التخزين المؤقت؟ هذا يؤدي إلى ما يسمى مشكلة N+1. يمكن أن يتجنب الرمز أعلاه مشكلة N+1. فكرتها هي استخدام القائمة () أولاً للاستعلام ، لأنه بعد الاستعلام عن القائمة () ، توجد البيانات في ملخص ذاكرة التخزين المؤقت من المستوى الأول ، وعند استخدام ITerator () ، ستكون الكفاءة عالية جدًا.
/*الاستعلام وفقًا للشروط (عادةً ما يتم استخدام الاسم المستعار هنا ، وهو أكثر ملاءمة)*/ LIST <Object []> students = session.createquery ("SELECT S.ID ، S.Name من STUTROM S حيث S.NAME مثل" ٪ 0 ٪ ""). قائمة () ؛ /*travel*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: الاستعلام المشروط هو نفسه SQL الأصلي ، وكلاهما هو المكان الرئيسي. بالإضافة إلى ذلك ، عادة ما يكون أكثر ملاءمة لاستخدام الاسم المستعار. البرنامج أعلاه هو الاستعلام عن سمات متعددة ، لذلك يقوم بإرجاع مجموعة من أنواع صفيف الكائن ، والعناصر الموجودة في صفيف الكائن هي السمات المقابلة.
/*CHENGED Programming*/ List <Object []> students = session.createquery ("Select S.ID ، S.Name from student s where s.name like؟") .SetParameter (0 ، "٪ 0 ٪") .List () ؛ /*travel*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: يمكن تمرير المعلمات من خلال العناصر النائبة ، والتي يمكن أن تمنع حقن SQL.
/*Programming*/ List <Object []> students = session.createquery ("SELECT S.ID ، S.Name from student s where s.name like: myName") .SetParameter ("myName" ، "٪ 0 ٪") .list () ؛ /*كائن صفيف*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasnext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: مثل: لا توجد مساحة بعد قولون اسم MyName ، وإلا فإن الخطأ سيحدث.
[java] عرض النسخ العادي/ * يعتمد الطريقة في الطريقة ، يمكن استخدام معلمة رسمية واحدة فقط */ list <object []> students = session.createquery ("SELECT S.ID ، S.NAME from student s s S.ID in (: ids)") .SetParameterlist ("ids" ، compour [] {1 ، 2 ، 3 ، 4 ، 5}). list () ؛ /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: لا يوجد سوى معلمة رسمية واحدة فقط في الأقواس بعد في. عندما نقوم بتعيين قيمة المعلمة ، يمكننا تمرير القيمة من خلال صفيف الكائن.
/* Query Students في 2009-08 ، يمكنك الاتصال بوظيفة تنسيق تاريخ MySQL*/ قائمة <Object []> الطلاب = session.createquery ("Select S.ID ، S.Name من STUTROM S DATE_FORMAT (S.CreateTime ، '٪ y-٪ m') =؟"). /*travel*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ } SimpleDateFormat sdf = جديد simpledateFormat ("Yyyy-MM-DD HH: MM: SS") ؛ /*يمكن للطلاب من 2009-08-01 إلى 2009-08-20 استدعاء وظيفة تنسيق تاريخ MySQL*/ LIST <Object []> students = session.createquery ("Select S.ID ، S.Name من S.CreateTime بين؟"). SDF.Parse ("2009-08-20 23:59:59")) .list () ؛ /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ } / * استخدم SELECT * يجب عليك استخدام عبارات SQL الأصلية ، وهي مشابهة للاستعلام عن خصائص متعددة HQL ، لذلك تقوم بإرجاع مجموعة من أنواع صفيف الكائن */ LIST <Object []> students = session.createsqlquery ("SELECT * from t_student"). list () ؛ /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: لا يدعم HQL نموذج الاستعلام لـ SELECT *، لكن السبات يدعم عبارات SQL الأصلية. يمكننا استخدام عبارات SQL للاستعلام. بالإضافة إلى ذلك ، فهو يشبه استعلام HQL المتعددة ، لذلك يرجع مجموعة من أنواع صفيف الكائنات.
/*استعلام الصفحة ، setFirStresult (1) يعني البدء من البيانات الأولى ؛ setMaxResult (2) تعني يتم عرض قطعتين من البيانات لكل صفحة*/ قائمة الطلاب = Session.Createquery ("من الطالب") .setFirStresult (1) .SetMaxResults (2) .List () ؛ /*travel*/ for (iterator iter = students.iterator () ؛ iter.hasnext () ؛) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ } /*sevigation Query ، S.Classes.name التنقل من الطالب إلى الدرس في الفصل (هذا يتنقل من المزيد إلى نهاية إلى نهاية ، وهو أمر ممكن أيضًا)*/ LIST <STUTROM> الطلاب = الجلسة. /*travel*/ for (iterator <Tudent> iter = student.iterator () ؛ iter.hasNext () ؛) {student student = (student) iter.next () ؛ system.out.println (student.getName ()) ؛ }ملحوظة: S.Classes.name في بيان الاستعلام أعلاه هو الحصول على اسم الفصل من التنقل الطالب إلى فصول الفصل. يمكنك أيضًا التنقل في العكس: انتقل من الفصل إلى الطالب في الحصول على سمة معينة. بالإضافة إلى ذلك ، يعني بيان الاستعلام في البرنامج الاستعلام عن جميع الطلاب مع 2 في اسم الفصل.
/ *الاتصال الداخلي ، ما عليك سوى استخدام الكلمة الأساسية JOIN */ LIST <Object []> students = session.createquery ("Select C.Name ، S.Name from student s join s s.classes c") .list () ؛ /*المعاملة*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: يتم الانضمام إلى الكلمة الرئيسية في الاتصال الداخلي ، ولا يزال الاتصال باستخدام الاسم المستعار والتنقل. يعني عبارة الاستعلام أعلاه: الاستعلام عن اسم الفصل واسم الطالب من جدول الطالب وجدول الفصل (يعني الاتصال الداخلي أنه يجب أن تكون هناك سمات جديرة في الاستعلام ، مثل عدم وجود فصل أو طلاب أو طلاب لا يمكنهم الاستعلام دون فصول).
/*join left يستخدم الكلمة الرئيسية اليسار join*/ list <Object []> students = session.createquery ("Select C.Name ، S.Name from student s left join s.classes c") .List () ؛ /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: يتم ترك الكلمة الرئيسية المستخدمة للانضمام الأيسر. تعني عبارة الاستعلام أعلاه: من طالب الطالب وجدول الفصل ، واستعل اسم الفصل واسم الطالب. نظرًا لأنه مرتبط باليسار ، سيتم أيضًا الاستعلام عن الطلاب الذين لا يوجد فصل دراسي.
[java] عرض النسخة العادية/*اليمين الكلمة الرئيسية هي الصحيح إلى الانضمام*/ list <object []> students = session.createquery ("حدد /*transip*/ for (iterator <object []> iter = student.iterator () ؛ iter.hasNext () ؛) {object [] obj = (object []) iter.next () ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: الكلمة الرئيسية باستخدام الوصلة الصحيح هي Joise Join. تعني عبارة الاستعلام أعلاه: من طالب الطالب وجدول الفصل ، واستعل اسم الفصل واسم الطالب. نظرًا لأنه مرتبط باليمين ، سيتم الاستعلام عن فصول بدون طلاب.
العد الطويل = (طويل) الجلسة.
ملاحظة: يمكن استخدام الاستعلامات الإحصائية فقط في HQL مع *. requeresult () يعني أن هناك مجموعة نتائج واحدة فقط ، والنوع الذي تم إرجاعه طويل.
/*بيان الاستعلام*/ string hql = "Select C.Name ، العد (S) من الفئات C Join C.Students s by C.Name Order by C.Name" ؛ قائمة <Object []> students = session.createquery (HQL) .List () ؛ /*travel*/ for (int i = 0 ؛ i <students.size () ؛ i ++) {object [] obj = (object []) students.get (i) ؛ system.out.println (obj [0] + "،" + obj [1]) ؛ }ملاحظة: يدعم HQL أيضًا التجميع ، والفرز ، وما إلى ذلك. يعني البيان أعلاه: الاستعلام عن اسم كل فصل والاستعلام عن عدد الطلاب في كل فصل ، مجموعة حسب اسم الفصل ، الفرز حسب اسم الفصل
ما سبق هو كل شيء عن مثال رمز استعلام HQL HQL في هذه المقالة ، وآمل أن يكون مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!