طرق مدمجة ل mapper
طبقة النموذج هي فئة الكيان ، المقابلة لجدول قاعدة البيانات. طبقة وحدة التحكم هي Servlet ، وهي مسؤولة بشكل أساسي عن التحكم في عملية وحدة العمل ، واتصال طريقة واجهة الخدمة ، وفي Struts2 هي الإجراء. تصدر طبقة الخدمة بشكل أساسي أحكامًا منطقية ، وطبقة DAO هي طبقة الوصول إلى البيانات ، التي تتصل بقاعدة البيانات. بالنسبة إلى Mapper ، يتم استخدام ملف تعيين Mapper في طبقة DAO.
فيما يلي وصف للطريقة المدمجة لـ Mapper:
1. countbyexample ===> Quep the الكمية وفقًا للشروط
int countByExample (مثال userexample) ؛ // فيما يلي قائمة حالات كاملة. userexample مثال = جديد userexample () ؛ معايير المعايير = مثال. createcriteria () ؛ المعايير. int count = userDao.countByexample (مثال) ؛
أي ما يعادل: حدد العد (*) من المستخدم حيث اسم المستخدم = "جو"
2. deletebyexample ===> حذف عناصر متعددة وفقًا للشروط
int deletebyexample (مثال Accountexample) ؛ // فيما يلي حالة كاملة userexample مثال = جديد userexample () ؛ معايير المعايير = مثال. createcriteria () ؛ المعايير. userDao.deleteByExample (مثال) ؛ أي ما يعادل: حذف من المستخدم حيث اسم المستخدم = "جو"
3. deleteberprimarykey ===> احذف عنصرًا واحدًا وفقًا للشروط
int deleteberprimarykey (integer id) ؛ userDao.DeleteByPrimarykey (101) ؛
أي ما يعادل:
حذف من المستخدم حيث المعرف = 101
4. إدراج ===> أدخل البيانات
int insert (سجل الحساب) ؛ // ما يلي هو مستخدم الحالة الكامل = مستخدم جديد () ؛ //user.setid(101) ؛ user.setUserName ("اختبار") ؛ user.setPassword ("123456") user.setemail ("[email protected]") ؛ userDao.insert (user) ؛أي ما يعادل:
أدخل في المستخدم (معرف ، اسم المستخدم ، كلمة المرور ، البريد الإلكتروني) القيم (101 ، "الاختبار" ، "123456" ، "[email protected]") ؛
5. إدراج البيانات ===> أدخل البيانات
int insertSeerTive (سجل الحساب) ؛
6. SelectByexample ===> بيانات الاستعلام بناءً على الشروط
قائمة <Corper> selectByExample (مثال AccounTexample) ؛ // فيما يلي حالة كاملة مثال userexample = جديد userexample () ؛ معايير المعايير = example.createcriteria () ؛ معايير. المستخدم حيث اسم المستخدم = "Joe" واسم المستخدم هو أمر فارغ بواسطة اسم المستخدم ASC ، البريد الإلكتروني desc // ملاحظة: يحتوي الملف userexample.java الذي تم إنشاؤه بواسطة Ibator على معايير فئة داخلية ثابتة. هناك العديد من الطرق في المعايير ، وخاصة لتحديد شروط الاستعلام بعد بيان SQL حيث.
7. SelectByPrimaryKey ===> بيانات الاستعلام بناءً على المفتاح الأساسي
حساب SelectByPrimaryKey (معرف INTEGER) ؛ // يعادل تحديد * من المستخدم حيث المعرف = معرف متغير
8. UpdateByExamplesElective ===> تحديث الحقول مع القيم ليست فارغة وفقًا للشروط
int UpdateByExamplesEctive (param ("record") سجل حساب ، param ("example") مثال accountexample) ؛ // فيما يلي قائمة حالات كاملة userexample مثال = جديد userexample () ؛ معايير المعايير = مثال. createcriteria () ؛ المعايير. مستخدم المستخدم = مستخدم جديد () ؛ user.setPassword ("123") ؛ userDao.updateByPrimaryKeySelective (المستخدم ، مثال) ؛ أي ما يعادل: تحديث المستخدم SET Password = '123' حيث اسم المستخدم = 'JOE'
9. تحديث updateByExamplesElective ===>
int UpdateByExample (param ("record") سجل حساب ، param ("example) accountexample مثال) ؛10. UpdateByPrimaryKeySelective ===> update وفقًا للشروط
int updateByPrimaryKeySelective (سجل حساب) ؛ // ما يلي هو مستخدم كامل لحالة المستخدم = مستخدم جديد () ؛ user.setid (101) ؛ user.setPassword ("joe") ؛ userDao.updateByPrimaryKeySeLext (المستخدم) ؛أي ما يعادل:
تحديث المستخدم SET Password = 'Joe' حيث id = 101
int updateByPrimaryKeySelective (سجل الحساب) ؛ // ما يلي هو مستخدم كامل لحالة المستخدم = مستخدم جديد () ؛ user.setId (101) ؛ user.setPassword ("joe") ؛ userDao.updateByPrimaryKeySelective (user) ؛أي ما يعادل: تحديث المستخدم SET Password = 'Joe' حيث id = 101
11. UpdateByPrimaryKey ===> اضغط على المفتاح الأساسي للتحديث
int updateByPrimaryKey (سجل الحساب) ؛ // ما يلي هو مستخدم كامل لحالة المستخدم = مستخدم جديد () ؛ user.setid (101) ؛ user.setUserName ("Joe") ؛ user.setPassword ("Joe") ؛ user.setemail ("[email protected]") ؛ userDao.updateByPrimaryKey (المستخدم) ؛أي ما يعادل:
تحديث المستخدم تعيين username = 'Joe' ، password = 'Joe' ، email = '[email protected]' حيث id = 101
int updateByPrimaryKey (سجل الحساب) ؛ // ما يلي هو مستخدم كامل لحالة مستخدم = مستخدم جديد () ؛ user.setid (101) ؛ user.setUserName ("Joe") ؛ user.setPassword ("Joe") ؛ user.setemail ("[email protected]") ؛ userDao.updateByPrimaryKey (المستخدم) ؛أي ما يعادل:
تحديث المستخدم تعيين username = 'Joe' ، password = 'Joe' ، email = '[email protected]' حيث id = 101
تحليل ملف تكوين XML الخاص بـ Mapper
دعنا نلقي نظرة على كيفية قراءة MyBatis لملف تكوين XML الخاص بـ Mapper وتوصيف عبارات SQL فيه.
ما زلنا نتذكر تكوين SQLSessionFactory مثل هذا:
<bean id = "sqlsessionfactory"> <property name = "datasource" ref = "datasource"/> <property name = "configlocation" value = "classpath: configuration.xml"> </sprement> <property name = "mapperlocations" value = "classpath: xxx/mybatis/mapper/. value = "com.tiantian.mybatis.model" /> </bean>
فيما يلي خاصية MapPerlocations ، وهو تعبير. ستقرأ SQLSessionFactory جميع ملفات تنسيق XML أسفل الحزمة com.xxx.mybaits.mapper وفقًا لهذا التعبير. فكيف تقرأ ملف التكوين بناءً على هذه السمة؟
الجواب في طريقة buildsqlsessionfactory في فئة SQLSessionFactorybean:
if (! isEmpty (this.mapperLocations)) {for (Resource MapPerLocation: this.mapperLocations) {if (mapperLocation == null) {stall ؛ } جرب {xmlmapperBuilder XmlMapperBuilder = جديد XmlMapperBuilder (mapperlocation.getInputStream () ، التكوين ، mapperlocation.toString () ، configuration.getsqlfragments ()) ؛ xmlmapperbuilder.parse () ؛ } catch (استثناء e) {رمي nestedioException جديد ("فشل في تحليل مورد رسم الخرائط:" + mapperlocation + "'" ، e) ؛ } أخيرًا {errorcontext.instance (). reset () ؛ } if (logger.isdebugenabled ()) {logger.debug ("ملف mapper المحسّن: '" + mapperlocation + "' ') ؛ }}}يستخدم MyBatis مثيلًا لفئة XMLMapperBuilder لتحليل ملفات تكوين Mapper.
Public XmlMapperBuilder (قارئ القارئ ، تكوين التكوين ، مورد السلسلة ، الخريطة <string ، xnode> sqlfragments) {this (new xPathparser (reader ، true ، configuration.getVariables () ، xmlmapperentityresolver ()) ، التكوين ، الموارد ، sqlfragments) ؛ } xmlmapperbuilder الخاص (محلل Xpathparser ، تكوين التكوين ، مورد السلسلة ، الخريطة <string ، xnode> sqlfragments) {super (configuration) ؛ this.builderassistant = جديد mapperBuilderAssistant (التكوين ، المورد) ؛ this.parser = محلل ؛ this.sqlfragments = sqlfragments ؛ this.resource = مورد ؛ }ثم يستدعي النظام طريقة تحليل xmlmapperBuilder لتحليل الخريطة.
Public void parse () {// إذا لم يتم تحميل كائن التكوين ملف تكوين XML (تجنب التحميل المكرر ، فهو في الواقع هو تأكيد ما إذا كانت خصائص ومحتوى عقدة mapper قد تم تحليلها ، / /تحضير // stream for to the streep of the mapper ، و parmper from from to to the mapper from from to to to the streep of the mapper from from from mapp strupe to the squar. تم تحميله if (! configuration.isresourceloaded (Resource)) {configurationEment (parser.evalnode ("/mapper") ؛ configuration.addloadedEdResource (Resource) ؛ bindMapperFornamesPace () ؛ } // تحليل العقدة <ReprontMap> التي لم تتم معالجتها عند معالجة resultmap في وظيفة التكوين. parsePendingResultMaps () ؛ // تحليل العقدة <Cache> غير موجودة عند معالجة Cache-REF في وظيفة التكوين (سيحدث هذا إذا تم تحميل Cache-REF قبل أن تشير عقدة ذاكرة التخزين المؤقت إلى) parsependingchacherefs () ؛ // كما هو مذكور أعلاه ، إذا لم يتم تحميل ذاكرة التخزين المؤقت ، فسيتم أيضًا إلقاء استثناء عند معالجة بيان ParsePendingStatements () ؛ }عملية MyBatis تحليل ملف XML الخاص بـ Mapper واضحة جدًا بالفعل. دعونا نلقي نظرة على كيفية خلط الخريطة:
configuration configurnement (Condex xnode) {try {// احصل على سمة مساحة الاسم لسلسلة سلسلة عقدة mapper = context.getStringAttribute ("مساحة الاسم") ؛ if (namepace.equals ("")) {رمي جديد builderexception ("مساحة اسم Mapper لا يمكن أن تكون فارغة") ؛ } // قم بتعيين مساحة الاسم الحالية builderassistant.setCurrentNamesPace (مساحة الاسم) ؛ // تحليل mapper <cache-ref> node cacherefelement (context.evalnode ("cache-ref")) ؛ // تحليل mapper <cache> العقدة cachelement (context.evalnode ("cache")) ؛ // تحليل mapper <parameTermap> node parametermapelement (context.evalnodes ("/mapper/parametermap")) ؛ // تحليل mapper <resultmap> node resultmapelements (context.evalnodes ("/mapper/resultMap")) ؛ // تحليل mapper <sql> node sqlelement (context.evalnodes ("/mapper/sql")) ؛ // استخدم كائن XmlStatementBuilder لتحليل mapper <select> ، <insert> ، <uptuday> ، <delete> ، // mybaits سوف تستخدم mappedStatement.Builder لإنشاء كائن chappedstatem BuildStatementFromContext (context.evalnodes ("SELECT | insert | update | delete")) ؛ } catch (استثناء e) {رمي جديد builderexception ("خطأ تحليل mapper xml. السبب:" + e ، e) ؛ }}تعمل وظيفة التكوين على توحيد جميع العقد الفرعية تقريبًا في عقدة Mapper. في هذه المرحلة ، تقوم MyBaits بتوزيع جميع العقد في Mapper وتضيفها إلى كائن التكوين لكائن SQLSessionFactory لاستخدامه في أي وقت. نحتاج هنا إلى إضافة بعض التفسير حول كيفية استخدام MyBaits وظيفة parsestatementnode لكائن فئة XmlStatementBuilder لاستعارة AddMappedStatement من MapPerBuilderAssistant Builderassistant لتستمر في mappedStatement وربطه إلى كائن فئة التكوين:
public void parsestatementNode () {// id attribute string id = context.getStringAttribute ("id") ؛ // databaseid سمة سلسلة databaseid = context.getStringAttribute ("databaseid") ؛ if (! databaseIdMatchesCrent (id ، databaseid ، this.requiredDatabaseId)) {return ؛ } // جلب السمة integer جلبها = context.getIntAttribute ("FetchSize") ؛ // timeout attribute integer timeout = context.getIntAttribute ("timeout") ؛ . // parametertype string string parametertype = context.getStringAttribute ("parametertype") ؛ class <؟> parametertypeclass = sesolveClass (parametertype) ؛ // resultmap string string resultmap = context.getStringAttribute ("resultMap") ؛ // resultType string string resultType = context.getStringAttribute ("resultType") ؛ // lang string string lang = context.getStringAttribute ("lang") ؛ LanguageRiver Langdriver = getLanguagedRiver (Lang) ؛ الفئة <؟> resultTypeClass = sesolveClass (resultType) ؛ . stitletype stitletytype = stittletype.valueof (context.getStringAttribute ("stittletype" ، stiteType.preped.toString ())) ؛ resultsettype resultsettypeenum = solveresultsettype (resultsettype) ؛ string nodename = context.getNode (). getNodename () ؛ sqlCommandType sqlCommandType = sqlCommandType.valueof (nodename.touppercase (locale.english)) ؛ // هل هو <select> node boolean isselect = sqlCommandType == SQLCommandTepe.Select ؛ // flushcache attribute boolean flushcache = context.getBooleAnattribute ("flushcache" ،! isselect) ؛ . // resultordered attribute boolean resultordered = context.getBooleAnattribute ("resultordered" ، false) ؛ // قم بتضمين شظايا قبل تحليل XmlinCludetRansformer includeParser = جديد XmlinCludetRansformer (التكوين ، builderassistant) ؛ includeparser.applyIncludes (context.getNode ()) ؛ // parse seleckekey بعد تضمينها وإزالتها. ProcessSelectKeynodes (ID ، ParametertyPeclass ، Langdriver) ؛ // تحليل SQL (pre: <selectekey> و <sckist> تم تحليلها وإزالتها) sqlsource sqlsource = langdriver.createsqlsource (التكوين ، السياق ، المعلمة expeclass) ؛ // results results property string regultets = context.getStringAttribute ("Results") ؛ . // keycolumn property string keycolumn = context.getStringAttribute ("keyColumn") ؛ KeyGenerator Keygenerator ؛ سلسلة keystatementid = id + selecteKeyGenerator.select_key_suffix ؛ keyStatementId = builderassistant.applyCurrentNamesPace (keystatementid ، true) ؛ if (configuration.hasKeyGenerator (keyStatementId)) {keygenerator = configuration.getKeyGenerator (keyStatementId) ؛ } آخر {// usegeneratedkeys keygenerator = context.getBooleAnattribute ("useGeneratedKeys" ، configuration.isusegeneratedKeys () && sqlcommandtype.insert.equals (sqlcommandtype))؟ New JDBC3KeyGenerator (): new noKeyGenerator () ؛ } builderassistant.addMappedStatement (ID ، SQLSource ، stittionType ، SqlCommandType ، FetchSize ، Timeout ، ParameTermap ، parametertypeclass ، resulttypeclass ، resultsettypeenum ، flushcache ، usecache ، keygeneratorator ، keycroperty ، keycolte. } من الكود أعلاه ، يمكننا أن نرى أن MyBaits يستخدم XPath لتحليل ملف تكوين Mapper ثم يقوم بإنشاء ResultMap و ParameTermap وذاكرة التخزين المؤقت والبيان والعقد الأخرى فيه باستخدام المنشئ المرتبط وربط الكائن الذي تم الحصول عليه في كائن التكوين. يمكن الحصول على كائن التكوين هذا من SQLSession ، وهو ما يفسر مشكلة كيف يحصل MyBaits على Mapper وتنفيذ عبارات SQL فيه عندما نستخدم SQLSession لتشغيل قاعدة البيانات.