وفقًا لفكرة الصفحة التالية ، من السهل تنفيذ التصميم المتعدد المستأجرين لـ Mybitas.
استخدم التقاطع الذي توفره MyBatis. تتم معالجة عبارات SQL المليئة بـ SQLs مختلفة من خلال التغليف.
لقد نفذ هذا المثال وظيفة ترقيم الصفحات لـ MySQL و Oracle. انتبه إلى حزمة الاقتباس التالية ولا تقتبسها بشكل غير صحيح.
استيراد java.sql.connection ؛ استيراد java.sql.preparedstatement ؛ استيراد java.sql.resultset ؛ استيراد java.sql.sqlexception ؛ import java.util.list ؛ import java.util.properties org.apache.ibatis.executor.Statement.RoutingStateMentHandler ؛ import org.apache.ibatis.executor.Statement.StateMentHandler ؛ import org.apache.ibatis.mappate.boundsql ؛ import org.ibatis.mapping.mapping org.apache.ibatis.plugin.Interceptor ؛ import org.apache.ibatis.plugin.Intercepts ؛ import org.apache.ibatis.plugin.Invocation ؛ import org.apache.ibatis.plugin org.apache.ibatis.scripting.defaults.defaultparameterhandler ؛ استيراد com.yidao.utils.page ؛ استيراد com.yidao.utils.reflecthelper ؛/** * * * interceptor. * يتم تنفيذ مبدأ ترحيل MyBatis باستخدام المعترضات: * لاستخدام JDBC للعمل على قاعدة البيانات ، يجب أن يكون لديك كائن عبارة مقابلة. قبل تنفيذ MyBatis عبارة SQL ، ستقوم بإنشاء كائن بيان يحتوي على عبارة SQL ، ويتم إنشاء عبارة SQL المقابلة* قبل البيان ، حتى نتمكن من البدء ببيان SQL المستخدم لإنشاء البيان قبل إنشاء البيان. في عبارة بيان MyBatis يتم إنشاؤها بواسطة طريقة إعداد * لكائن RoutingStateMentHandler. لذلك ، فإن إحدى الأفكار الخاصة باستخدام اعتراض لتنفيذ ترحيل MyBatis هو اعتراض طريقة إعداد واجهة HOHDFACE ، ثم تغيير عبارة SQL إلى عبارة الاستعلام المقابلة SQL في طريقة الاعتراض ، ثم استدعاء طريقة إعداد كائن * stateHandler ، أي استدعاء call.proceed (). * بالنسبة إلى ترقيم الصفحات ، فإن إحدى العمليات التي يتعين علينا القيام بها في الاعتراض هو حساب إجمالي عدد السجلات التي تلبي الشروط الحالية. هذا هو عن طريق الحصول على عبارة SQL الأصلية ، وتغييره إلى البيان الإحصائي المقابل ، ثم استبدال المعلمات في عبارة SQL باستخدام المعلمات المغلفة MyBatis ومعلمات الإعداد *. بعد ذلك ، يتم تنفيذ عبارة SQL التي تستفسر عن عدد السجلات لحساب إجمالي عدد السجلات. * */ intercepts ({ @signature (type = itshandler.class ، method = "prepared" ، args = {connection.class})}) Public PageInterceptor يقوم بتنفيذ interceptor {private string dialect = "" "؛ // Database Dialect Private String pagesqlid = "" ؛ // المعرف الذي يجب اعتراضه في mapper.xml (مطابقة منتظمة) اعتراض الكائن العام (استدعاء الاحتجاج) يلقي رمي {// هناك بالفعل فئتان فقط للتنفيذ لـ itshandhandler ، أحدهما هو RoutingStateMentLer ، والآخر هو الفئة التجريدية basestemhandler. // BasestatementHandler لديه ثلاث فئات فرعية ، وهي SimplestateMentHandler و WreparedStatementHandler و CallablestateMentHandler. // يتم استخدام SimplesTateMentHandler لمعالجة البيان ، ومقابض WearryStateMentHandler ، و CallablestateMentHandler IS // معالجة callablesTatement. MyBatis ينشئ RoutingStatementHandler عند معالجة عبارات SQL. في RoutingStateMentHandler ، هناك خاصية مندوب من // itshandler type. سيقوم RoutingStateMentHandler بإنشاء قاعدة أساسية مقابلة وفقًا للبيانات المختلفة ، أي ، أبسط Handler ، // ReadyStateMentHandler أو CollablestateMentHandler. في RoutingStateMentHandler ، يتم تنفيذ جميع طرق واجهة ItSTINGHALLLER بواسطة المندوب المقابل للمندوب المسمى. //قمنا بتمييز التقاطع فقط عن طريقة إعداد واجهة itshandler مع signature على فئة pageInterceptor. نظرًا لأن MyBatis يلفها فقط من خلال طريقة Interceptor Plugin عند إنشاء RoutingStateMentHandler ، لذلك يجب أن يكون الكائن المستهدف الذي نعترضه هنا هو كائن RoutingStateMentHandler. if (invocation.getTarget () مثيل routingStateMentHandler) {RoutingStateMentHandler stitpller = (RoutingStateMentHandler) invocation.getTarget () ؛ مندوب ittureHandler = (stittleHandler) respectHelper.getFieldValue (ittiptHandler ، "DeLegate") ؛ BODEDSQL BOODSQL = DEPEGATE.GETBOUNDSQL () ؛ Object obj = boundsql.getParameterObject () ؛ if (OBJ مثيل page <؟>) {page <؟> page = (page <؟>) obj ؛ // استرجع خاصية MedpedStatement لـ basestatementHandler من فئة الوالدين المندوبين mappedStatement MedpedStatement = (mappedStatement) respectHelper.getFieldValue (مندوب ، "MedPedStatement") ؛ // معلمة طريقة التحضير المعترض هي اتصال كائن اتصال = (اتصال) // احصل على عبارة SQL التي تم تنفيذها حاليًا ، أي عبارة SQL التي نكتبها مباشرة في سلسلة Mapper Mapping SQUL = BONDSQL.GETSQL () ؛ // قم بتعيين إجمالي عدد السجلات لكائن معلمة الصفحة الحالي this.settotalRecord (صفحة ، medpedStatement ، الاتصال) ؛ // احصل على page pageql pagesql = this.getpagesql (صفحة ، sql) ؛ // استخدم الانعكاس لتعيين سمة SQL المقابلة للحدود الحالية لإنشاء عبارة SQL جيدة المهدئة بالنسبة لنا respectHelper.setFieldValue (BODEDSQL ، "SQL" ، pagesql) ؛ }} return invocation.proceed () ؛ } /*** قم بتعيين إجمالي عدد السجلات لصفحة كائن المعلمة الحالية** PARAM PAGE MAPPER عبارة* param mappedstatement mapper mapping* param connection connection curraction* /private void settoTalRecord (page <؟> page ، mappedStatement MedpedStatement ، connection) {// الحصول على الحدود المرتبطة. هذا الحدود هو في الواقع نفس كائن الحدود التي حصلنا عليها باستخدام stitpleHandler. // يتم الحصول على الحدود في المندوب أيضًا من خلال طريقة medpedStatement.getBoundSQL (paramobj). BODEDSQL BOODSQL = MEDPEDSTATEMTEMT.GETBOUNDSQL (صفحة) ؛ // احصل على سلسلة بيانات SQL المقابلة SQL = BONDSQL.GETSQL () ؛ // احصل على عبارة SQL المقابلة التي تحسب العدد الإجمالي للسجلات عن طريق الاستعلام عن سلسلة بيانات SQL countsql = this.getCountSQL (SQL) ؛ // احصل على خريطة المعلمة المقابلة من خلال قائمة BOUNDSQL <ParmeterMapping> paramEterMappings = bONDSQL.GetParamEterMappings () ؛ // استخدم التكوين ، countsql بيان SQL للاستعلام ، ورسم خرائط المعلمة parametermappings وصفحة كائن المعلمة لإنشاء كائن BODESQL يتوافق مع سجلات الاستعلام. boundsql countBoundSql = new BODEDSQL (MEPTSTATEMANTEMTEMNED.GETCONFIGURATION () ، COUNTSQL ، PARMETERMAPPINGS ، PAGE) ؛ // قم بإنشاء كائن parameterHandler لتحديد المعلمات من خلال medstatement ، صفحة كائن المعلمة و countBoundSql countboundsql boundsql. parameterHandler ParameterHandler = New DefaultParameterHandler (MapPedStatement ، page ، countboundsql) ؛ // قم بإنشاء كائن reparedstatement المقابل لـ CountsQL من خلال الاتصال. ReparedStatement PSTMT = NULL ؛ resultset rs = null ؛ حاول {pstmt = connection.preparestatement (countsql) ؛ // اضبط المعلمات المعلمة للكائن الجدد من خلال parameterHandler.setParameters (PSTMT) ؛ // ثم يتم تنفيذها للحصول على إجمالي عدد السجلات والحصول على النتائج. rs = pstmt.executequery () ؛ if (rs.next ()) {int totalRecord = rs.getInt (1) ؛ // قم بتعيين إجمالي عدد السجلات لكائن صفحة المعلمة الحالي. }} catch (sqlexception e) {E.PrintStackTrace () ؛ } أخيرًا {try {if (rs! = null) rs.close () ؛ if (pstmt! = null) pstmt.close () ؛ } catch (sqlexception e) {E.PrintStackTrace () ؛ }}} / ** * SQL عبارة عن إجمالي العدد المقابل للسجلات في الاستعلام * param sql * regurn * / private string getCountsql (String sql) {int index = sql.indexof ("من") ؛ إرجاع "تحديد COUNT (*)" + sql.substring (index) ؛ } /*** احصل على عبارة SQL SQL بناءً على كائن الصفحة. يتم إجراء نوعين فقط من قواعد البيانات هنا ، MySQL و Oracle * لا توجد قواعد بيانات أخرى هي ترحيل * * param paging كائن * param sql sql state */ string private getPagesQl (الصفحة <؟ if ("mysql" .equalsignoreCase (Dialect)) {return getMySqlPagesQl (page ، sqlbuffer) ؛ } آخر إذا ("oracle" .equalsInsInsEcase (لهجة)) {return getoraclepagesql (page ، sqlbuffer) ؛ } return sqlbuffer.toString () ؛ } / *** احصل على عبارة الاستعلام المهدئة لقاعدة بيانات MySQL* كائن Param Page Paging* param sqlbuffer stringbuffer كائن يحتوي على عبارة SQL الأصلية* @REGAL MYSQL DATABASE DATABASE BAGE* / private string getMySQLPagesQL (الصفحة <؟ يبدأ موضع السجل في MySQL من 0. // system.out.println ("الصفحة:"+page.getPage ()+"--------"+page.getRows ()) ؛ int arsom = (page.getPage () - 1) * page.getRows () ؛ sqlbuffer.append ("limit") .append (إزاحة). إرجاع sqlbuffer.toString () ؛ } / *** احصل على عبارة الاستعلام المفرطة لـ Oracle Database* Param Page Paging Object* param sqlbuffer stringbuffer كائن يحتوي على عبارة sql الأصلية* Query Query Query Return for Oracle Database* / private string getoraclepagesql (الصفحة <؟ يتم تنفيذ ترقيم Oracle من خلال Rownum ، ويبدأ Rownum من 1 int الإزاحة = (page.getPage () - 1) * page.getRows () + 1 ؛ sqlbuffer.insert (0 ، "Select u.*، rownum r from (") .Append (") u where rownum <"). sqlbuffer.insert (0 ، "SELECT * from (") .Append (") where r> =") .Append (Offset) ؛ // يبدو أن عبارة SQL أعلاه مثل هذا: // حدد * من (SELECT u. * ، rownum r from (select * from t_user) u حيث rownum <31) حيث r> = 16 return sqlbuffer.toString () ؛ } / *** طريقة لتغليف الكائن الأصلي المقابل للمكون الإضافي لـ Interceptor* / Public Object (Object Arg0) {// todo method method method if (arg0 attupthandler) {return plugin.wrap (arg0 ، this) ؛ } آخر {return arg0 ؛ }} / *** قم بتعيين الخصائص التي تم تعيينها عند تسجيل interceptor* / public void setProperties (الخصائص p) {} السلسلة العامة getDialect () {return dialect ؛ } public void setDialect (string dialect) {this.dialect = dialect ؛ } السلسلة العامة getPagesQLid () {return pagesqlid ؛ } public void setPagesQlid (سلسلة pagesqlid) {this.pagesqlid = pagesqlid ؛ }} تكوين XML:
<!-تكوين برمجة واجهة MyBatis-> <bean> <!-يحدد BasePackage الحزمة المراد مسحها. سيتم البحث في التعيينات تحت هذه الحزمة. يمكن تحديد حزم متعددة ، مفصولة بفواصل أو فاصلة منقوطة-> <property name = "basePackage" value = "com.yidao.mybatis.dao" /> <property name = "sqlsessionfactoryname" value = "sqlsessionfactory" /> < /! name = "dialect" value = "mysql"/> <!-اعتراض العبارة مع معرف يحتوي على أحرف الاستعلام في ملف mapper.xml-> <property name = "pagesqlid" value = ".
صف الصفحة
package com.yidao.utils ؛/** انظر إليها بنفسك ، ما هي الحقول اللازمة لإضافتها*/صفحة الفئة العامة {صفوف عدد صحيح ؛ صفحة عدد صحيح خاص = 1 ؛ عدد صحيح خاص TotalRecord ؛ عدد صحيح عام getrows () {return rows ؛ } public void setRows (integer rows) {this.rows = rows ؛ } integer getPage () {return page ؛ } public void setPage (صفحة integer) {this.page = page ؛ } integer getTotalRecord () {return totalRecord ؛ } public void settoTalRecord (Integer TotalRecord) {this.totalRecord = TotalRecord ؛ }} انعكاس فئة
package com.yidao.utils ؛ import java.lang.reflect.field ؛ import org.apache.commons.lang3.reflect.fieldutils ؛ class public classhelper {public static object getFieldValue (object obj ، string fieldname) {if (obj == null) {return null ؛ } Field TargetField = getTargetField (obj.getClass () ، fieldName) ؛ جرب {return fieldUtils.Readfield (TargetField ، OBJ ، true) ؛ } catch (alfictAccessException e) {e.printStackTrace () ؛ } إرجاع فارغ ؛ } الحقل الثابت العام getTargetField (الفئة <؟> TargetClass ، string fieldName) {field field = null ؛ حاول {if (targetClass == null) {return field ؛ } if (object.class.equals (targetClass)) {return field ؛ } field = fieldUtils.getDeclaredField (TargetClass ، fieldName ، true) ؛ if (field == null) {field = getTargetField (targetclass.getSuperClass () ، fieldName) ؛ }} catch (استثناء e) {} حقل الإرجاع ؛ } public static void setFieldValue (Object obj ، string fieldName ، قيمة الكائن) {if (null == obj) {return ؛} field targetfield = getTargetField (obj.getClass () ، fieldName) ؛ جرب {fieldUtils.writeField (TargetField ، OBJ ، value) ؛ } catch (alfictAccessException e) {e.printStackTrace () ؛ }}}ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.