بعد العمل الجاد لعدة ليال لتصحيح البرنامج ، وكتابة العديد من المدونات ، وأخيراً إنشاء آلية التوسع لتكوين MyBatis. على الرغم من أن آلية التمديد مهمة ، إلا أنها ليست ملهمة على الأقل إذا لم تكن هناك وظيفة تمديد عملية حقًا. ستمنحك هذه المدونة بعض الأمثلة على الامتدادات.
سبب هذه الدراسة للرمز المصدر هو التوافق بين قواعد بيانات Oracle و MySQL. على سبيل المثال ، باستخدام خطوط عمودية مزدوجة كموصلات في Oracle ، واستخدام وظيفة COST في MySQL ؛ على سبيل المثال ، استخدام دالة Decode في Oracle ، مع استخدام الحالة القياسية فقط عندما يكون في MySQL ؛ على سبيل المثال ، حذف جدول النماذج حيث يمكن تنفيذ Field1 In (تحديد جدول Field1 حيث يمكن تنفيذ Field2 =؟) ، ولكن سيتم طرح الاستثناءات في MySQL ، إلخ.
لنبدأ بحل مشكلات التوافق هذه. أولاً ، تحتاج إلى إضافة تكوينات متعلقة بالهوية قاعدة البيانات إلى التكوين:
<!-بناء كائن التكوين بنفسك-> <bean id = "mybatisconfig"/> <bean id = "sqlsessionfactory" p: dataSource-ref = "dataSource"> <! name = "mapperlocations"> <Sray> <value> classpath*: **/*. يتم استخدام MySQL كقاعدة البيانات في التكوين. الكلمات الرئيسية للتنفيذ الأصلي MyBatis حساسة للحالة. لم أختبر Oracle و DB2 -> <prop key = "mysql"> mysql </prop> <prop key = "oracle"> oracle </prop> <prop key = "h2"> h2 </prop> <prop key = "db2"> db2 </prop> </props> </pertar
1. مشكلة الموصل
1. اكتب فئة تنفيذ دالة تكوين SQL
يمتد COLLONSQLCONFIGFUNCTIONS من الطبقة العامة upplicationsqlConfigFunction {// يتم تعيين مستوى الطلب الافتراضي في سلسلة parent classe orderridepublic getName () {return "concat" ؛} @that @string string eval (string databaseid ، string [] {if (args.length <2) وسيطات. ") ؛} if (" mysql ".equalsignoreCase (databaseId)) {return" concat ("+tool.string.join (args ،" ، ")+")2. سجل في كتلة الرمز الثابت لفئة Schemahandlers ، أو استدعاء طريقة Schemahandlers في فئة تهيئة بدء التشغيل.
ثابت {// register stateHandlerRregister ("cache-ref" ، cacherefstateMentHandler ()) ؛ تسجيل ("ذاكرة التخزين المؤقت" ، cachestatementhandler ()) sqlstatementHandler ()) ؛ register ("SELECT | insert | update | delete" ، new CrudStatementHandler ()) ؛ // قم بتسجيل ScripthandlerRegister ("trim" ، new tripscripthandler () foreachscripthandler ()) ؛ register ("if | when" ، new IfScripthandler ()) ؛ registrice ("اختر" ، new choinscripthandler ()) ؛ dbStatementHandler () ، dbscripthandler ())بالإضافة إلى تسجيل concatsqlConfigfunction ، يحتوي الكود أعلاه أيضًا على بعض رموز التسجيل الأخرى ، والتي يتم تقديمها هنا وسيتم حذفها أدناه.
3. تعديل تكوين SQLMAPPER
<حدد ID = "selectString" resultType = "string"> حدد param_name ، $ concat {param_code ، param_name} as code_name from bf_param_enum_def <if test = "null! = paramname و '! = paramname"> حيث param_name مثل $ concat {' ٪ '، '٪'} </if> </select>4. اكتب فئة الواجهة
repositorypublic interface iexampledao {public string selectString (param ("paramname") سلسلة paramname) ؛}5. اكتب فصول الاختبار
RunWith (SpringJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classpath: spring/applicationContext.xml"}) Dao.SelectString ("Show") ؛ Assert.assertequals ("منطقة العرض" ، أ) ؛}}6. قم بتشغيل كما يلي في MySQL و H2 على التوالي (اضبط مستوى سجل MyBatis للتتبع)
(1) MySQL
20161108 00: 12: 55،235 [main]-[debug] ==> preparing: select param_name ، concat (param_code ، param_name) as code_name from bf_param_enum_def where param_name مثل concat ('٪' ،؟ ، '٪') 20161108 00: 12: 55،269 (سلسلة) 20161108 00: 12: 55،287 [MAIN]-[TRACE] <== الأعمدة: param_name ، code_name20161108 00: 12: 55،287 [main]-[trace] <= row row: display_area display area201108 00: 12: 55،289(2) H2
20161108 00: 23: 08،348 [main]-[debug] ==> preparing: select param_name ، param_code || param_name as code_name from bf_param_enum_def where param_name like '٪' || '٪' 20161108 00: 08،364 00: 23: 08،411 [main]-[trace] <== الأعمدة: param_name ، code_name20161108 00: 23: 08،411 [main]-[trace] <== row: display ، display_area display area20161108 00: 23: 08،411 [main]
كما ترون ، تم حل مشكلة توافق الموصلات.
بالإضافة إلى ذلك ، وجدنا أيضًا أن الكتابة أكثر إزعاجًا عند استخدام الكلمات الرئيسية ، لذلك دعونا نقدمها مجموعة جديدة من وظائف تكوين SQL:
الفئة العامة LiSESQLConfIgFunctionFactory تنفذ ISQLConfigFunctionFactory {Overridepublic Collection <IsqlConfigFunction> getSqlConfigFunctions () {return arrays.aslist (getleftlikesqlconfunction () ، getRightlikesqlconfunction () getLikesQlConfigFunction ()) ؛} private isqlConfigFunction getleftlikesqlconfunctive () {return new AbstractLikesQlConfUnction () {@@string string getName () {return "like" ؛ $ concat {'٪' ، "+arg+"} "؛}} ؛} private isqlConfIgFunction getRightLikesQlConfIgFunction () {return new AbstractLikesQlConfUnction () $ concat {"+arg+" ، '٪'} "؛}} ؛} private isqlConfIgFunction getLikesQlConfIgFunction () {return new AbstractLikesQlConfUnction () {@@sturdepublic getName () {return" ؛ $ concat {'٪' ، "+arg+" ، '٪'} "؛}} ؛} private erction class upplictlikesqlConfUnction يمتد الملخصات upplysqlConfIgFunction {ordridepublic almost (ad or or or or or or or or or or or or or or order ad argument. eval (args [0]) ؛} سلسلة تجريدية محمية (سلسلة arg) ؛}}هنا ، يتم تعريف مجموعة من وظائف تكوين SQL ، مع التشابه الأيسر ، والتشابه الأيمن ومطابقة التشابه الأوسط ، ويمكن أيضا أن تكون وظائف تكوين SQL متداخل. لذلك ، يتم تبسيط ملف التكوين لـ SQLMapper إلى:
<حدد ID = "SELECTSTRING" resultType = "string"> حدد param_name ، $ concat {param_code ، param_name} كـ code_name من bf_param_enum_def <null = "null! = paramname و ''! = paramname"نتائج التشغيل هي نفسها بالضبط.
إذا كنت لا تزال تجدها مزعجة ، لأن param_name و parmname هما مراسلات تشبه الجمل ، يمكنك حتى إضافة وظيفة مثل الحقل وتعديل التكوين إلى
حيث $ fieldlike {#{param_name ، jdbctype = varchar}}إذا تم دمجه مع قاموس البيانات ، يمكن أيضًا إنشاء تكوين JDBCTYPE تلقائيًا:
حيث $ fieldlike {#{param_name}}في هذه الحالة ، إذا كانت هناك معلمات متعددة ، فلن يكون هناك أي غموض (أو وظيفة تكوين محددة حديثًا $ LEG {} سيتم استخدامها للقضاء على الغموض) ، لذلك يمكن تبسيط شروط متعددة إلى:
حيث يحب $ {#{param_name ، param_name2 ، param_name3}}بالطبع ، هناك المزيد من التبسيطات القابلة للحفر التي لم تعد فقط في نطاق التوافق ، لذلك لن نذهب إلى أبعد من ذلك.
2. فك تشفير الوظيفة/الحالة ... متى
وظيفة فك التشفير في Oracle مريحة للغاية ، وبناء الجملة كما يلي:
Decode (الشرط ، القيمة 1 ، قيمة الإرجاع 1 ، القيمة 2 ، قيمة الإرجاع 2 ، ... القيمة N ، قيمة الإرجاع N [، القيمة الافتراضية]))
الكتابة القياسية للمكافئات:
حالة الحالة عندما تكون القيمة 1 ثم قيمة الإرجاع 1 عندما تكون القيمة 2 ثم قيمة الإرجاع 2 ... عندما تكون القيمة n ثم قيمة الإرجاع n
الآن دعنا ننفذ وظيفة تكوين Decode $:
decodesqlConfUnction تمدد الملخصات actractsqlConfIgFunction {Overridepublic String getName () {return "decode" ؛ وسيطات. ") ؛} if (" H2 .equalsInsInsIgnorEcase (databaseid)) {// عند الاختبار ، استخدم H2 بدلاً من Oracle ، وقم بتعديله إلى Oraclereturn في البرنامج الرسمي "decode ("+toot.string.join (args ، "،")+")" ") .append (args [0]) ؛ int i = 2 ، l = args.length ؛ for (؛ i <l ؛ i = i+2) {sb.append (" when ") .append (args [i-1]). sb.append ("else") .append (args [l-1]) ؛} sb.append ("end") ؛ return sb.toString () ؛}}}ثم استخدم Schemahandlers لتسجيل وتعديل التكوين في SQLMapper:
<حدد ID = "selectString" resultType = "string"> حدد param_name ، $ decode {#{paramname} ، '1' ، 'a' ، '2' ، 'b' ، 'c'} كـ decode_test من bf_param_enum_def <test = "null! = paramname و '! jdbctype = varchar}} </if> </select>الاختبارات هي كما يلي:
(1) في H2 (استبدل Oracle بـ H2)
20161108 06: 53: 29،747 [main]-[debug] ==> preparing: select param_name ، decode (؟ ، '1' ، 'a' ، '2' ، 'b' ، 'c') as decode_test from bf_param_def where param_name like '٪'
(2) في MySQL
20161108 06: 50: 55،998 [Main]-[Debug] ==> Preparing: Select Param_Name ، Case؟ عندما يكون "1" ثم "A" عندما يكون "2" ثم "B" آخر "C" كأنه decode_test من bf_param_enum_def حيث param_name مثل "٪ '||؟ ||' ٪ '
ما سبق هو مقدمة مفصلة لتمديد وتطبيق تكوين SQLMapper في MyBatis الذي قدمه لك المحرر (1). آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!