هناك العديد من القيود عند استخدام MyBatis وحده (مثل عدم القدرة على تنفيذ المعاملات التي تمتد على جلسات متعددة) ، والعديد من أنظمة الأعمال هي في الأصل معاملات تتم إدارتها بحلول الربيع ، لذلك من الأفضل دمج MyBatis مع الربيع.
متطلبات الإصدار
مشروع | إصدار | تنزيل عنوان | يوضح |
mybatis | 3.0 وما فوق | https://github.com/mybatis/mybatis-3/releases | |
ربيع | 3.0 وما فوق | http://projects.spring.io/spring-framework/ | |
mybatis-spring | 1.0 وما فوق | https://github.com/mybatis/spring/release |
<!-المسح التلقائي لحزم الأعمال-> <السياق: مكون-المسح القاعدة = "com.xxx.service"/> <!-مصدر البيانات-> <je: jndi-lookup id = "jndidataSource" jndi-name = "java: env/jdbc/dataSource"/> <! <property name = "datasource" ref = "jndidatasource"/> </bean> <!-تكوين الأشياء المستندة إلى التعليقات التوضيحية AOP-> <tx: معاملة المعاملة التي تعتمد على التعليقات التوضيحية = "txmanager" proxy-target-class = "true"/>
تكامل واحد
<!-تكامل MyBatis-> <bean id = "sqlsessionfactory"> <property name = "datasource" ref = "jndidatasource" /> <property name = "configlocation" value = "classPath: /MyBatis/Mybatis-Config.xml" value = "com.xxx.dto" /> </bean> <!-إنشاء DAO BEAN (فقط قم بتوفير واجهات ولكن ليس فئات التنفيذ)-> <bean id = "userdao"> <property name = "mapperinterface" value = "com.xxx.dao.userdao
يجب ألا نفهم فقط كيفية استخدامه ، ولكن أيضًا نفهم سبب استخدامنا له مثل هذا.
SQLSessionFactoryBean هي فول المصنع ، ووظائفها هي تحليل التكوينات (مصدر البيانات ، الاسم المستعار ، إلخ).
MapPerfactorybean هو فول المصنع. في حاوية الربيع ، فإن حبوب المصنع لها استخدامات خاصة. عندما يضخ الربيع حبوب المصنع في الفاصوليا الأخرى ، فإنه لا يضخ حبة المصنع نفسه ولكنه يطلق على طريقة getObject الخاصة بالفاصوليا. دعونا نلقي نظرة على ما تفعله طريقة getObject هذه:
place g getObject () يلقي استثناء {return getSqlSession (). getMapper (this.mapperInterface) ؛ }بعد رؤية هذا ، يجب أن تفهم أن هذه الطريقة هي نفسها كما استخدمنا MyBatis وحده. نحصل أولاً على كائن SQLSession ، ثم نحصل على كائن Mapper من SQLSession (مقابل Mapper هو كائن وكيل ، والذي يتخلى عن واجهة واجهة Mapper ، وهذه الواجهة هي واجهة DAO التي يوفرها المستخدم). وبطبيعة الحال ، فإن الحقن النهائي في طبقة العمل هو كائن الخريطة هذا.
بشكل عام ، هناك أكثر من مشروع واحد. إذا كان لديك مشاريع متعددة ، فقم بتكوينها بالتسلسل وفقًا للتكوين أعلاه.
كيفية استخدام تحديثات الدُفعات
تحدث القسم السابق عن كيفية حقن كائن Mapper في طبقة العمل. يعتمد سلوك Mapper على التكوين. يستخدم MyBatis تحديثًا واحدًا افتراضيًا (أي أن Executortype الافتراضي بسيط بدلاً من الدفعة). بالطبع ، يمكننا تعديل السلوك الافتراضي عن طريق تعديل ملف تكوين MyBatis ، ولكن إذا كنا نريد فقط واحد أو عدة محاصر لاستخدام تحديثات الدُفعات ، فلا يمكن القيام به. في هذا الوقت ، نحتاج إلى استخدام تكنولوجيا القالب:
<!-تخصيص سلوك myBatis من خلال القوالب-> lt ؛ id bean = "sqlsessionTemplatesImple"> <constructor-arg index = "0" ref = "sqlsessionfactory"/> <!-update في وضع واحد-< id = "sqlsessionTemplateBatch"> <constructor-arg index = "0" ref = "sqlsessionfactory"/> <!-update in a batch mode-> <constructor-arg index = "1" "value =" batch "/> </ban>
هنا ، يحدد المؤلف كائنين من القالب ، أحدهما يستخدم تحديثًا واحدًا والآخر باستخدام تحديث الدُفعات. بعد أن يكون لدينا القالب ، يمكننا تغيير الطريقة التي يتصرف بها Mapper:
<bean id = "userDao"> <property name = "mapperInterface" value = "com.xxx.dao.userdao" /> <property name = "sqlsessionTemplate" ref = "sqlsessionTemplateBatch" /> </bean>
تختلف عن تكوين Mapper في القسم السابق ، ليست هناك حاجة لتكوين خاصية SQLSessionFactory هنا ، تحتاج فقط إلى تكوين SQLSessionTemplate (تم تكوين خاصية SQLSessionFactory في القالب).
تبسيط تكوين التعيينات مع المسح التلقائي
كما ترون في الفصل السابق ، يحتاج DAO إلى تكوين واحد تلو الآخر في ملف التكوين. إذا كان هناك العديد من DAO ، فسيكون ملف التكوين كبيرًا جدًا ، والذي سيكون أكثر إيلامًا لإدارته. لحسن الحظ ، أدرك فريق Mybatis هذا أيضًا. لقد استخدموا وظيفة المسح التلقائي التي توفرها SPRING لتغليف فئة الأدوات التي تقوم بمسح تلقائي ، حتى نتمكن من استخدام هذه الوظيفة لتبسيط التكوين:
<!-إنشاء فول Mapper باستخدام المسح التلقائي (وضع التحديث الفردي)-> <bean> <property name = "basePackage" value = "com.xxx.dao" /> <property name = "sqlsessionTemplateBeanname" value = "sqlsessionTEmplateMple <!-قم بإنشاء فول Mapper باستخدام المسح التلقائي (وضع تحديث الدُفعات)-> <Bean> <property name = "basePackage" value = "com.xxx.dao" /> <property name = "sqlSessionTemplateBeanname" value = "sqlsessiontemplateBatch" /> <propert
لن أتحدث عن تقنية الربيع المشاركة في MappersCannerConfigurer نفسها. إذا كنت مهتمًا ولديك فهم جيد لمبادئ الربيع ، فيمكنك التحقق من رمز المصدر الخاص به. دعونا نركز على خصائصه الثلاثة:
بالإضافة إلى استخدام تصفية الواجهة ، يمكنك أيضًا استخدام تصفية التعليقات التوضيحية:
<!-قم بإنشاء Mapper Bean باستخدام المسح التلقائي (وضع تحديث الدُفعات)-> <Bean> <property name = "basePackage" value = "com.xxx.dao" /> <property name = "sqlsessionTemplateBeanname" value = "sqlsessionTemplateBatch" /> <propert
التعليقات التوضيحية: فقط عند تكوين التعليقات التوضيحية ، سيتم مسحها ضوئيًا بواسطة الماسح الضوئي ، والاستعادة هي وظيفة نفس الشيء.
تجدر الإشارة إلى أنه يمكن مطابقة واحدة فقط من شروط المرشح.
مثال: إدارة المعاملات
تحديد فئة الكيان: emp.java
package com.lixing.scm.entity ؛ public class emp {private string id ؛ اسم السلسلة الخاصة ؛ جنسية سلسلة خاصة عصر INT الخاص ؛ سلسلة سلسلة خاصة ؛ السلسلة العامة getId () {معرف الإرجاع ؛ } public void setId (string id) {this.id = id ؛ } السلسلة العامة getName () {return name ؛ } public void setName (اسم السلسلة) {this.name = name ؛ } سلسلة عامة getSex () {return sex ؛ } public void setSex (سلسلة الجنس) {this.sex = sex ؛ } public int getage () {return Age ؛ } public void setage (int age) {this.age = age ؛ } السلسلة العامة getPhone () {return phone ؛ } public void setphone (سلسلة الهاتف) {this.phone = phone ؛ }} حدد واجهة التشغيل الداخلية: empmapper.java
package com.lixing.scm.test.mapper ؛ import java.util.list ؛ import java.util.map ؛ import com.lixing.scm.entity قائمة <emp> getAllemp () ؛ EMP getByid (string id) ؛ void releteemp (string id) ؛ void updateemp (خريطة <سلسلة ، كائن> خريطة) ؛}
تحديد ملف التعيين لواجهة تشغيل فئة الكيان: empmapper.xml
<؟ مساحة name.lixing.scm.test.mapper.empmapper "> <parameTermap type =" com.lixing.scm.entity.emp "id =" parametermapemp "> <parameter property =" id "/> <parameter propert type = "com.lixing.scm.entity.emp" id = "resultMapemp"> <result property = "id" column = "id"/> <result property = "name" column = "name"/> <result properial = "sex" column = "sex"/> <result propert parameTerMap = "parameTerMapemp"> إدراج في EMP (المعرف ، الاسم ، الجنس ، العمر ، الهاتف) قيم (؟ ،؟ ،؟ ،؟ ،؟) </insert> <select id = "getAlemp </select> <delete id = "deletem" parametertype = "string"> delete من emp where id =#{value} </delete> <update id = "updateemp" parametertype = "java.util.map"> update emp set name =#{name} ، sex =# </update> </mapper> spring3.0.6 التعريف: ApplicationContext.xml <؟ Xmlns: XSI = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/Aop http://www.springframework.org/schema/aop/spring-aop-3 value = "classpath: jdbc.properties" /> </bean> <bean id = "myDataSource" Destroy-method = "close"> <property name = "driverClassName" value = "$ {jdbc.driverclassname}" /> <property name = "$ {jdbclo} value = "$ {jdbc.username}" /> <property name = "password" value = "$ {jdbc.password}" /> </bean> <!-sqlsessionfactory-> <bean id = "sqlsessionfactory> <property name =" datasource "ref = name = "basePackage" value = "com.lixing.scm.test.mapper" /> </bean> <!- ================================================================سف name = "TransactionManager"> <property name = "dataSource" ref = "myDatasource"> </property> </bean> <tx: explive id = "usertxAdvice" Transaction-Manager = "TransactionManager"> <TX: Countributes> <tx: method name = "delete*propergation = read-only = no-Rollback-for = "java.lang.runtimeexception" /> <tx: method name = "insert*" spection = "required" read-only = "false" rollback-for = "java.lang.runtimeexception" /> <tx: method update = "spression =" read-road- " <tx: method name = "find*" spection = "supports"/> <tx: method name = "get*" spection = "supports"/> <tx: method name = "select*" spection = "supports"/> </tx: attributes> </tx: explive> <aop: config> com.lixing.scm.test.service.*.*(..)) " /> <!-معاملات التحكم في مستوى الخدمة-> <aOP: Advisor PointCut-REF =" PC "evide-ref =" usertxAdvice " /> < /aop: config> <! AutoWire = "ByName"/> </bans> واجهة داو: Empdao.java
package com.lixing.scm.test.dao ؛ import java.util.list ؛ import java.util.map ؛ import com.lixing.scm.entity قائمة <emp> getAllemp () ؛ EMP getByid (string id) ؛ void releteemp (string id) ؛ void updateemp (خريطة <سلسلة ، كائن> خريطة) ؛}
فئة تنفيذ واجهة DAO: EMPDAOIMPL.JAVA
package com.lixing.scm.test.dao.impl ؛ import java.util.list ؛ import java.util.map ؛ import com.lixing.scm.entity empmapper // حقن empmapper هنا // يتم إنشاء هذا empmapper تلقائيًا بواسطة spring // لا نحتاج إلى تحديد oudride public void insertemp (EMP) {this.empmapper.insertemp (EMP) ؛ رمي جديد RunTimeException ("خطأ") ؛ // اختبار يلقي RunTimeException // استثناء لمعرفة ما إذا كانت قاعدة البيانات لديها سجلات} Override Public Void Deleteemp (string id) {this.empmapper.deleteMp (id) ؛ } Override Public List <Emp> getAllemp () {return this.empmapper.getAllemp () ؛ } Override Public Emp getById (string id) {return this.empmapper.getById (id) ؛ } Override public void updatemp (map <string ، Object> map) {this.empmapper.updateemp (map) ؛ } public empmapper getempmapper () {return empmapper ؛ } public void setMeMapper (empmapper empmapper) {this.empmapper = empmapper ؛ }} واجهة طبقة الخدمة: empservice.java
package com.lixing.scm.test.service ؛ استيراد com.lixing.scm.entity.emp ؛ الواجهة العامة empservice {void insertemp (EMP) ؛} فئة تطبيق واجهة طبقة الخدمة: EmpserviceImpl.java
package com.lixing.scm.test.service.impl ؛ import com.lixing.scm.entity.emp ؛ import com.lixing.scm.test.dao.empdao ؛ import com.lixing.scm.test.service.empservice ؛ public class empserviceimpl dispsservice {private empdao ؛ Override public void insertemp (emp emp) {empdao.insertemp (emp) ؛ } public empdao getempdao () {return empdao ؛ } public void setempdao (empdao empdao) {this.empdao = empdao ؛ }} فئة الاختبار: attempservice.java
استيراد org.junit.test ؛ استيراد org.springframework.context.applicationContext ؛ استيراد org.springframework.context.support.classpathxmlapplicationContext testTrasaction () {emp emp = new emp () ؛ Emp.SetId ("00000003") ؛ Emp.SetName ("某某某") ؛ Emp.Setage (50) ؛ Emp.SetSex ("ذكر") ؛ Emp.SetPhone ("566666") ؛ ApplicationContext CTX = جديد classpathxmlapplicationContext ("classPath: ApplicationContext.xml") ؛ خدمة Empservice = ctx.getBean (empservice.class) ؛ service.insertemp (EMP) ؛ }}