تنفيذ استعلام مشترك متعدد الطاولة
أو قم بإنشاء فئة موقع ويب جديد ضمن حزمة David.mybatis.model لاستمرار البيانات وإعادة كتابة طريقة ToString () المقابلة لتسهيل استخدام برامج الاختبار.
package david.mybatis.model ؛ import java.text.simpledateformat ؛ import java.util.date ؛ موقع الطبقة العامة {private int id ؛ اسم السلسلة الخاصة ؛ Private Int VisitorId ؛ حالة int الخاصة ؛ تاريخ خاص CreateTime ؛ زائر خاص الزائر ؛ موقع الويب العام () {// TODO Auto الذي تم إنشاؤه تلقائيًا CreateTime = New Date () ؛ زائر = زائر جديد () ؛ } موقع الويب العام (اسم السلسلة ، int visitorid) {this.name = name ؛ this.visitorid = visitorid ؛ زائر = زائر جديد () ؛ الحالة = 1 ؛ createTime = تاريخ جديد () ؛ } public int getId () {return id ؛ } public void setId (int id) {this.id = id ؛ } الزائر العام getVisitor () {return visitor ؛ } public void setVisitor (زائر الزوار) {this.visitor = visitor ؛ } السلسلة العامة getName () {return name ؛ } public void setName (اسم السلسلة) {this.name = name ؛ } public int getStatus () {return status ؛ } public void setStatus (int status) {this.status = status ؛ } التاريخ العام getCreateTime () {return createTime ؛ } public void setCreateTime (DateTeTime) {this.createTime = createTime ؛ } public int getVisitorId () {int id = 0 ؛ إذا (زائر == فارغ) معرف = VisitorId ؛ else id = visitor.getId () ؛ معرف الإرجاع ؛ } public void setVisitorId (int visitorid) {this.visitorid = visitorid ؛ } Override Public String ToString () {StringBuilder SB = New StringBuilder (string.format ("Website => {id: ٪ d ، name: ٪ s ، createTime: ٪ s}/r/n" ، id ، name ، simpleDateFormat new ("yyyy-mm-dd hh: mm: ss"). if (visitor! = null) sb.append (string.format ("visitor => ٪ s" ، visitor.toString ())) ؛ إرجاع sb.tostring () ؛ }}قم بإنشاء واجهات العملية المقابلة تحت david.mybatis.demo:
package david.mybatis.demo ؛ import java.util.list ؛ import david.mybatis.model.website ؛ public interface iwebsiteOperation {public int add (موقع الويب) ؛ الحذف العام (int id) ؛ تحديث int العام (موقع الويب) ؛ استعلام موقع الويب العام (INT ID) ؛ القائمة العامة <Sealch> getList () ؛ }قم بإنشاء ملف تعيين WebSITEMAPPER.xml جديد في مجلد Mapper ، والرجوع إلى الملف السابق لإضافة وحذف وتعديل والتحقق من تكوين تشغيل الجدول المفرد ، بحيث يمكنك إنشاء بعض بيانات الاختبار. على النحو التالي
<؟ مساحة الاسم = "david.mybatis.demo.iwebbsiteOperation"> <sql id = "getListsQl"> حدد المعرف ، الاسم ، الزوار ، الحالة ، createTime من موقع الويب> 0 </sql> <insert id = "add" ، adgantype = "website" usegeneratedkys = ( #{name} ، #{visitorid} ، #{status} ، #{createTime}) </insert> <delete id = "delete" parametertype = "int"> delete from were where status> 0 and id = #{id} </redet id =#{id} </uptuday> <select id = "query" parametertype = "int" resultmap = "websiters"> حدد موقع الويب. موقع الويب. javatype = "visitor" resultmap = "visitorrs" /> < /resultmap> <resultmap type = "visitor" id = "visitors"> <id column = "visitorid" = "id" /> <result column = "visitorname" property = "name" /> /> </select> </prapper>ما نتحدث عنه اليوم هو البحث. الآن نريد الاستعلام عن موقع الويب وإخراج معلومات الزائر المقابلة معًا. كيف تفعل ذلك؟ يمكنك الرجوع إلى الاستعلام في التكوين وكتابة SQL لاستعلام جدول الارتباط.
الشيء الرئيسي الذي يجب ملاحظته هنا هو أن خصائص الهوية والاسم في كيان الموقع وزيارة الكيان هي نفسها. لذلك ، من أجل تجنب تعيين الأخطاء ، سرد نتائج الاستعلام المقابلة مع الاسم المستعار المختلفة ، بحيث يمكن تجنبها عند الربط.
ماذا سأحصل إذا قمت بتكوينه مثل ما يلي؟
<حدد id = "query" parametertype = "int" resultmap = "websisters"> حدد موقع الويب. website.id =#{id} </select> <resultMap type = "website" id = "websisters"> <id column = "id" property = "id" /> <result column = "sitename" property = "name" /> <result column = "sitestatus" property = "status" /> resultmap = "visitorrs" /> </sroperedmap> <resultmap type = "visitor" id = "visitorrs"> <id column = "id" property = "id" /> <result column = "visitorname" propert هل لاحظت أن معرف الزائر أصبح أيضًا 2. في الواقع ، يقوم بتخطيط معرف الموقع افتراضيًا ، لأن نتيجة استعلام بيان SQL قد أصبحت 2. قد يسأل بعض الأشخاص عن سبب عدم كونه 4 ، لأنها تطابق أول واحد بشكل افتراضي. إذا قمت بتبديل مواقع الموقع .ID و TIST.ID ، فستجد أن النتيجة قد تغيرت بطريقة سحرية مرة أخرى.
لذلك تحتاج إلى إعطاء اسم مستعار لتجنب هذا الموقف ، لذلك ستجد أن هناك حقيقة واحدة فقط ، وهي ما يلي:
يمكنك أن ترى أن طريقة نتائج المعالجة متعددة الطاولة هي نفس طريقة الجداول الفردية. إنه ليس أكثر من سرد اسم سمة جافابان. يمكنك أن ترى أن هناك خريطة أخرى في مكتب الاستقبال في عقدة <nreductmap> للموقع. إنه يمثل الكيان الذي يجب تعيينه بواسطة كيان الزيارة. يمكنك استخدام الطريقة التالية لصنع الارتباطات.
<Association Property = "Visitor" Javatype = "Visitor" resultMap = "Visitorrs" />
الزائر هو اسم حقل الزيارة في كيان الموقع. يجب أن يكون الاسم متسقًا. خلاف ذلك ، لا يوجد استثناء من أي مكان للممتلكات المسماة "xxx" في "class david.mybatis.model.website" سيتم إلقاؤه. وقد تم وصف هذا في الفصول السابقة. بالطبع ، إذا كنت تعتقد أنه من الجيد عدم Nest ResultMap ، فإن التعشيش يرجع أيضًا إلى حقيقة أنه يمكن استخدام هذا التكوين في مكان آخر ، فسيتم استخلاصه ، وهي أيضًا فكرة مجردة. استخدم المعرف والنتائج في <redrectmap> للعثور على الاختلافات المقابلة من الموقع الرسمي: http://mybatis.github.io/mybatis-3/sqlmap-xml.html#result_maps
وبهذه الطريقة ، سيظهر استعلام مفصل بسيط متعدد الطاولة. إذا كانت هناك رسوم أعمال استعلام أكثر تعقيدًا ، فسيتم إجراء بعض التعديلات بناءً على هذا.
المنطق تأثير ترقيم الصفحات
ما نريد التحدث عنه هو مشكلة ترقيم الصفحات التي نواجهها في كثير من الأحيان في مشكلة العمل. عند تطوير مشاريع الويب ، غالبًا ما نستخدم عرض القائمة. بشكل عام ، نستخدم بعض عناصر التحكم في القائمة شائعة الاستخدام ، مثل DataTables (أشعر شخصيًا بحالة جيدة جدًا) ، وعناصر التحكم في الجدول المغلف تحت واجهة المستخدم السهلة.
فكرة: لتحقيق تأثير الترحيل في هذه الضوابط ، نمر عادة 2 معلمات. الأول هو تمثيل فهرس الصفحة الحالية (عادةً ما تبدأ من 0) ، والثاني هو تمثيل عدد سجلات الأعمال التي يتم عرضها على الصفحة الحالية ، ثم تمرير المعلمات المقابلة إلى القائمة <T> getList (Pagenateargs args). عند تنفيذ الترحيل أخيرًا في قاعدة البيانات ، يمكننا استخدام الكلمة الرئيسية الحد (لـ MySQL) للترحيل. إذا كان خادم Oracle أو SQL ، فلديهم جميعًا وظيفة Rownum الخاصة بهم لاستخدامها.
لمعالجة الأفكار المذكورة أعلاه ، أولاً وقبل كل شيء ، نحتاج إلى إنشاء فئة كيان معلمة صفحة جديدة تسمى Pagenateargs تحت demo.mybatis.model كما هو الحال دائمًا ، وفئة التعداد المسماة sortdirectionenum ، والتي تحتوي على مؤشر الصفحة الحالي ، و Page Page Prison Pagesizes ، و pagestart يوضح العنصر الذي يبدأ من. (PageStart = pageIndex*pagesize) لأن استخدام الكلمة الرئيسية للحد هو تمثيل [رقم بدء الحد (غير مدرج) ، خذ بعض العناصر] ، حقل فرز OrderFieldstr ، اتجاه فرز OrderDirectionSt ، وبالتالي فإن الإنشاء المحدد هو كما يلي:
حزمة david.mybatis.model ؛
/ * * pagination parmeter creytity class */public class pagenateargs {private int pageIndex ؛ pagesize pagesize ؛ PAGESTART الخاص. سلسلة خاصة OrderFieldstr ؛ سلسلة orderdirectionstr الخاصة ؛ PagenateArgs () {// TODO تلقائيًا كعب باغناتيرغز (int pageIndex ، int pagesize ، string orderfieldstr ، string orderdirectionstr) {this.pageindex = pageIndex ؛ this.pagesize = pagesize ؛ this.orderfieldstr = orderfieldstr ؛ this.orderDirectionStr = orderdirectionStr ؛ Pagestart = pageIndex * pagesize ؛ } public int getPageIndex () {return pageIndex ؛ } public int getPagestart () {return pagestart ؛ } public int getPagesize () {return pagesize ؛ } السلسلة العامة orderfieldstr () {return orderfieldstr ؛ } السلسلة العامة getorderDirectionStr () {return orderdirectionstr ؛ }} package david.mybatis.model ؛/ * * sort enum */public enum sortdirectionenum {/ *]بعد الانتهاء من الخطوات المذكورة أعلاه ، نستمر في إضافة طريقة عامة للأسلوب <Sititor> getListByPagenate (Pagenateargs args) إلى فئة واجهة IvisitorOperation. في الفصول السابقة ، لدينا بالفعل طريقة GetList. هذا الترقيم هو في الواقع مجرد تغيير بسيط بناء على هذا. بعد تغيير فئة واجهة Ivisitoroperation ، فهي كما يلي:
package david.mybatis.demo ؛ import java.util.list ؛ import david.mybatis.model.pagenateargs ؛ import david.mybatis.model.visitor ؛ import david.mybatis.model.visitorwithrn ؛ public interface ivisitoroperation {** query query* /** إضافة زائر*/ int العام إضافة (زائر الزائر) ؛ /** حذف الزائر*/ public int delete (int id) ؛ /** تحديث الزائر*/ int public update (زائر الزوار) ؛ /** استعلام زائر*/ استعلام الزوار العام (INT ID) ؛ / * * قائمة الاستعلام */ قائمة عامة <Sisitor> getList () ؛ / * * قائمة الاستعلام عن ترقيم الصفحات */ قائمة عامة <Sisitor> getListByPageNate (Pagenateargs args) ؛ }بعد ذلك ، يتعين علينا أن نبدأ في تغيير ملف تكوين VisitorMapper.xml الخاص بنا ، أضف معرف Node الجديد ونوع المعلمة لتكوينه وفقًا للفصول السابقة. المعرف الجديد المضافة هنا هو getListByPagenate. بعد التكوين ، ما يلي
<؟ <!-usegeneratedKeys = "true" تعني ما إذا كان يجب استخدام تسلسل النمو الذاتي ، يحدد keyproperty = "id" عمود النمو الذاتي ، المعلمة = "الزوار" يحدد النوع المقابل الذي تم تمريره في التعريف "edeproperty". أدخل في الزائر (الاسم ، البريد الإلكتروني ، الحالة ، createTime) القيم ( #{name} ، #{elem} ، #{status} ، #{createTime}) </insert> <delete id = "delete" parametertype = "int" =#{name} ، البريد الإلكتروني =#{البريد الإلكتروني} ، الحالة =#{الحالة} حيث id =#{id} و status> 0 ؛ </uptuday> <select id = "query" parametertype = "int" resultType = "Visitor"> حدد المعرف ، الاسم ، البريد الإلكتروني ، الحالة ، createTime من الزائر حيث id =#{id} و status> 0 order by id </select> <تحديد المعرف = "basicquery" المعلمة = int </select> <select id = "getList" resultmap = "visitors"> <refid = "getListsql"/> </select> <sql id = "getListsql"> SELECT * من الزائر حيث الحالة> 0 </sql> <!- ما يلي جزء جديد للترخيص. يتم استخراج orderbysql على سبيل المثال إعادة استخدام لاحقًا-> <resultmap type = "visitor" id = "visitors"> <id column = "id" property = "id" /> <result column = "name" property = "name" /> <resumber column = "elem elemt id = "getListByPagenate" parametertype = "pagenateargs" resultType = "Visitor"> SELECT * from (<refid = "getListsql" /> <refid = "orderbysql" />) Pagesize> -1 "> limit #{pagestart} ، #{pagesize} </fort> </select> <sql id =" orderbysql "> order by $ {orderfieldstr} $ {orderdirectionstr} </sql> </sql>ستجد تكوينات مماثلة في الشكل أدناه. تتوافق جميع سمات الحقل هنا مع أسماء السمات في فئة المعلمة Pagenateargs.
<if test = "pagestart> -1 و pagesize> -1"> limit #{pagestart} ، #{pagesize} </forقم بإنشاء طريقة اختبار في فئة Demorun:
/** معلمات ترقيم الصفحات*/public queryvisitorlistsitorlistwithpagenate (int pageIndex ، int pagesize ، string orderfield ، string orderdire) {pagenateargs args = new pagenateargs (pageIndex ، pagesize ، orderdfield ، orderdire) ؛ SQLSession Session = MyBatisutils.getSqlSession () ؛ ivisitoroperation voperation = session.getMapper (ivisitoroperation.class) ؛ قائمة <Sisitor> الزوار = voperation.getListByPageNate (args) ؛ لـ (زائر الزوار: الزوار) {system.out.println (زوار) ؛ } mybatisutils.closesession (جلسة) ؛ mybatisutils.showmessages (crud_enum.list ، الزوار.demorun.queryvisitorlistwithpagenate (0 ، 100 ، "id" ، sortdirectionenum.desc.toString ()) ؛
بعد التشغيل ، يتم فرز نتائج الاختبار بترتيب عكسي في IDS. هناك 14 سجل في جدول الزوار.
لنفترض أننا نأخذ 5 قطع في الصفحة 2 ، وننفذ قطع البيانات 6-10 التالية ، لذلك فقط تمرير المعلمات.
demorun.queryVisitorListWithPagenate (1 ، 5 ، "id" ، sortdirectionenum.desc.toString ()) ؛
النتائج كما يلي:
هذا هو منطق الترحيل الذي قمت بتطبيقه بنفسي ~^0^. ما تحتاج إلى ملاحظته هنا هو أنني لم أصدر أي حكم على حقل OrderFieldstr هنا. من الناحية النظرية ، من الضروري التعامل معها لمنع تمرير أسماء الأعمدة الخاطئة. ومع ذلك ، يجب أن يكون هناك تغليف جاهز على الإنترنت الآن ، بحيث يمكنك أيضًا الذهاب إلى Google. فيما يلي مجرد طريقة لإظهار كيفية استخدام ترحيل MyBatis.
بعد الانتهاء من هذا ، لأنه MySQL ، ليس لديه معرف تسلسل Rownum الخاص به في نتيجة الاستعلام. لذلك ، قد لا يكون من الواضح عند التحقق من بيانات الاختبار. إذا لم يكن عليك التعجيل ، فيمكننا أن نفعل ذلك بنفسك للتعويض عن الطعام والملابس وتحويل الطريقة أعلاه. هنا سأقوم بإنشاء كيان متطابق تمامًا في حزمة النماذج وأحضر معرفًا إضافيًا يتم إرجاعه من خلال استمرار معلمة Rownum ، على النحو التالي:
package david.mybatis.model ؛ import java.text.simpledateformat ؛ import java.util.date ؛ public class pisorterwithrn {private int id ؛ اسم السلسلة الخاصة ؛ البريد الإلكتروني الخاص بالسلسلة الخاصة ؛ حالة int الخاصة ؛ تاريخ خاص CreateTime ؛ int int rownum ؛ Public VisitorWithrn () {// TODO تلقائيًا تم إنشاؤه تلقائيًا CreateTime = New Date () ؛ } الزائر العام (اسم السلسلة ، البريد الإلكتروني السلسلة) {this.name = name ؛ this.email = البريد الإلكتروني ؛ this.setStatus (1) ؛ this.createTime = تاريخ جديد () ؛ } public int getId () {return id ؛ } public void setName (اسم السلسلة) {this.name = name ؛ } السلسلة العامة getName () {return name ؛ } public void setemail (string email) {this.email = email ؛ } السلسلة العامة getEmail () {return email ؛ } التاريخ العام getCreateTime () {return createTime ؛ } public int getStatus () {return status ؛ } public void setStatus (int status) {this.status = status ؛ } public int getRownum () {return rownum ؛ } public void setRownum (int rownum) {this.rownum = rownum ؛ } Override public string toString () {// todo method method string string.format ("{rownum: ٪ d ، id: ٪ d ، name: ٪ s ، createTime: ٪ s}" ، rownum ، id ، name ، simpledateformat ("yyyy-mm-dd hh: mm: ss"). }}في IvisitorOperation ، قم بإنشاء طريقة جديدة تسمى القائمة العامة <SititorWithrn> getListByPagenateWithrn (Pagenateargs args). وبالمثل ، نحتاج إلى تكوين <select> العقدة والبرنامج النصي المقابل في VisitorMapper. الفرق الوحيد هنا هو أننا نحتاج إلى تعديل البرنامج النصي SQL ، على النحو التالي:
<؟ <!-usegeneratedKeys = "true" تعني ما إذا كان يجب استخدام تسلسل النمو الذاتي ، يحدد keyproperty = "id" عمود النمو الذاتي ، المعلمة = "الزوار" يحدد النوع المقابل الذي تم تمريره في التعريف "edeproperty". أدخل في الزائر (الاسم ، البريد الإلكتروني ، الحالة ، createTime) القيم ( #{name} ، #{elem} ، #{status} ، #{createTime}) </insert> <delete id = "delete" parametertype = "int" =#{name} ، البريد الإلكتروني =#{البريد الإلكتروني} ، الحالة =#{الحالة} حيث id =#{id} و status> 0 ؛ </uptuday> <select id = "query" parametertype = "int" resultType = "Visitor"> حدد المعرف ، الاسم ، البريد الإلكتروني ، الحالة ، createTime من الزائر حيث id =#{id} و status> 0 order by id </select> <تحديد المعرف = "basicquery" المعلمة = int </select> <select id = "getList" resultmap = "visitors"> <refid = "getListsql" /> </select> <sql id = "getListsql"> select * from pasoritor where where where eid = id "idens = regund <spense <side <spense = regud <scense = regud <spense". column = "البريد الإلكتروني" الخاصية = "البريد الإلكتروني" /> <result column = "status" property = "status" /> <result column = "createTime" property = "createTime" /> < /resultmap> <select id = "getListByPagenate refid = "orderbysql"/>) t <!- #{} يعني الإخراج المعلم ، $ {} يعني أن الإخراج المباشر لا يؤدي أي عمليات هروب ، ونقله بنفسك-> <إذا test = "pagestart> -1 و pagesize> -1"> limit #{pagestart} ، #{pagesize} id = "orderbysql"> order by $ {orderfieldstr} $ {orderdiretationstr} </sql> <!-كيفية كتابة نصوص sql باستخدام rownum-> <resultmap type = "column =" name = "column =" propert property = "email" /> <result column = "status" property = "status" /> <result column = "createTime" property = "createTime" /> <result column = "rownum" property = "rownum" /> </sultresup> <select id = لا تنفيذ أي عمليات هروب ، قم بنقلها بنفسك-> حدد T.Rownum ، T.ID ، T.Name ، T.Email ، T.Status ، T.CreateTime من (<تضمين refid = "getListsqlContainsrn" /> <suption refid = "orderbysql" />) #{pagesize} </if> </select> <sql id = "getListsqlContainsrn"> select rownum: = @rownum+1 rownum ، result.id ، result.name ، result.email ، result.status ، result.createTime from (select rownum: = 0 ، from late state> 0). الشيء التالي المتبقي هو إضافة طريقة الاختبار تحت Demorun الآن ، لذلك لن ألصق الخريطة هنا. بعد الانتهاء ، يمكنك أن ترى أن قطع البيانات من 6 إلى 10 سنوات ستصبح الآن على النحو التالي