จุดเริ่มต้นของ MyBatis Pagination
มีแนวคิดของปลั๊กอิน (ปลั๊กอิน) ใน mybatis ซึ่งเป็นแนวคิดการสกัดกั้นเป็นหลัก การวิเคราะห์เฉพาะสามารถพบได้ในการวิจัยเกี่ยวกับหลักการของ mybatis interceptor ในบทความอื่น บนพื้นฐานนี้บทความนี้จะแสดงรหัสการใช้งานโดยตรงของโครงการจริงและการวิเคราะห์อื่น ๆ ที่เกี่ยวข้อง
การใช้งานรหัสเฉพาะเพจ
ก่อนอื่นเราสามารถกำหนดคลาสบทคัดย่อภาษาถิ่นเพื่อใช้การแบ่งแยก pagination AbstractDialect.java
บทคัดย่อระดับสาธารณะ AbstractDialect { / *** รองรับขีด จำกัด และชดเชยได้รับการสนับสนุน* @return* / Public Public Boolean SupportLimitOffset (); / ** * รองรับขีด จำกัด * @return */ Public Abstract Boolean SupportLimit (); / ** * รับ SQL หลังจากเพิ่มแอตทริบิวต์ Paging * @Param SQL * @Param Offset * @Param Limit * @return */ สตริงนามธรรมสาธารณะ getLimitString (String SQL, int offset, int ขีด จำกัด );};นอกจากนี้เราจะใช้เทคโนโลยีเพจเพจหน้าของฐานข้อมูล Oracle และ MySQL แยกกัน
mysqldialect.java-mysql pagination ภาษา
คลาสสาธารณะ MySqldialect ขยาย AbstractDialect {บูลีนสาธารณะสนับสนุน SlimitOffset () {return true; } บูลีนสาธารณะ supportslimit () {return true; } สตริงสาธารณะ getLimitString (String SQL, int offset, int ขีด จำกัด ) {if (Offset> 0) {return SQL + "Limit" + Offset + "," + Limit; } else {return SQL + "Limit" + Limit; -oracledialect.java-oracle การใช้งานภาษาถิ่น
ชั้นเรียนสาธารณะ OracleDialect ขยาย adialect {@Override บูลีนสาธารณะ supportLimitOffset () {return false; } @Override Public Boolean SupportLimit () {return false; } @Override สตริงสาธารณะ getLimitString (String SQL, int start, int ขีด จำกัด ) {if (start <0) {start = 0; } if (ขีด จำกัด <0) {limit = 10; } StringBuilder PageSql = new StringBuilder (100); PagesQl.Append ("เลือก * จาก (เลือก Temp. *, Rownum Row_id จาก ("); PagesQl.Append (SQL); PagesQl.Append (") อุณหภูมิที่ Rownum <=") return pagesql.toString (); -การใช้งาน MyBatis Plug-In Interceptor ที่สอดคล้องกันมีดังนี้: Intercept ConttementHandler#เตรียม (การเชื่อมต่อ cON) เพื่อสร้างเมธอดวัตถุคำสั่ง SQL
PaginationInterceptor.java
@Intercepts ({@signature (type = stementhandler.class, method = "เตรียม", args = {connection.class})}) ระดับสุดท้ายของคลาสสุดท้าย paginationinterceptor ใช้ interceptor ภาษา Adialect ส่วนตัว โมฆะสาธารณะ setDialect (ภาษา Adialect) {this.dialect = ภาษาถิ่น; } @Override การสกัดกั้นวัตถุสาธารณะ (การเรียกร้องการเรียกใช้) โยน {// ได้รับโดยตรงโดยตรงวัตถุซึ่งใช้การกำหนดเส้นทางคลาส StatementHandler คำชี้แจง handler attementler = (คำสั่ง handler) การเรียกใช้. getTarget (); BoundSQL BUNTSQL = คำชี้แจง HANDLER.GETBOUNDSQL (); // รับ MetaObject ส่วนใหญ่ใช้เพื่อรับวัตถุและแอตทริบิวต์ที่เกี่ยวข้องกับคำสั่ง metaobject metaObject metastatementhandler = metaobject.forobject (stementhandler, defaultObjectFactory ใหม่ (), defaultObjectWrapperFactory () ใหม่); MappedStatement mappedstmt = (MappedStatement) MetastatementHandler .getValue ("Delegate.mappedStatement" .intern ()); // เฉพาะวิธีการ querypagination () ถ้า (mappedstmt.getId (). indexof ("querypagination") ==-1) {return invocation.proceed (); } // สร้าง Paging SQL String OriginalsQl = (String) MetastatementHandler .getValue ("Delegate.boundsql.sql" .intern ()); MetastatementHandler.SetValue ("Delegate.boundsql.sql" .intern (), ภาษาถิ่น .getLimitstring (OriginalsQl, Rowbounds.getOffset (), rowbounds.getLimit ()); MetastatementHandler.SetValue ("Delegate.RowBounds.Offset" .intern (), rowbounds.no_row_offset); MetastatementHandler.SetValue ("Delegate.Rowbounds.limit" .intern (), rowbounds.no_row_limit); log.debug ("หน้า sql:" + boundsql.getsql ()); return rachation.proceed (); } // Intercept Object @Override Public Object ปลั๊กอิน (เป้าหมายวัตถุ) {return plugin.wrap (เป้าหมายสิ่งนี้); } @Override โมฆะสาธารณะ setProperties (คุณสมบัติคุณสมบัติ) {}}การกำหนดค่า XML ที่สอดคล้องกันของสปริงอาจเป็นดังต่อไปนี้การทำ oracle pagination เป็นตัวอย่าง
<!-การกำหนดค่าภาษาถิ่น Oracle ใช้สำหรับ Oracle Pagination-> <bean id = "paginationInterceptor"> <property name = "ภาษาถิ่น"> <bean/> </porement> </ebean>
ใช้รหัสด้านบนและการกำหนดค่าเพื่อดำเนินการ pagination ของฐานข้อมูล Oracle และฐานข้อมูล MySQL และบล็อกเกอร์วิเคราะห์หนึ่งในคะแนน
mybatis#metaobject-metadata การวิเคราะห์วัตถุ
เมื่อบล็อกเกอร์ใช้รหัสข้างต้นเขารู้สึกงงงวยกับคลาส MetaObject มันสามารถรับคุณสมบัติที่เกี่ยวข้องทั้งหมดของวัตถุที่ถูก proxyed ผ่านวิธี getValue () โดยตรง เราสามารถติดตามซอร์สโค้ดเพื่อเรียนรู้เพิ่มเติม
MetaObject#forObject()
วัตถุพร็อกซีทั้งหมดเข้าสู่วิธีการคงที่นี้
public Static MetaObject forObject (วัตถุวัตถุ, ObjectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {ถ้า (object == null) {ส่งคืน systemmetaobject.null_meta_object; } else {ส่งคืน metaobject ใหม่ (Object, ObjectFactory, ObjectWrapperFactory); -เราสามารถสังเกตตัวสร้างโดยตรงนี่คือความลึกลับ
Private MetaObject (Object Object, ObjectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {this.originalObject = Object; this.ObjectFactory = ObjectFactory; this.ObjectWrapperFactory = ObjectWrapperFactory; // การได้มาซึ่งแอตทริบิวต์ทั้งหมดได้รับผ่านคลาส ObjectWrapper ที่นี่เราตัดสินประเภทวัตถุวัตถุที่เป็นพร็อกซีหาก (วัตถุอินสแตนซ์ของ ObjectWrapper) {this.ObjectWrapper = (ObjectWrapper) วัตถุ; } อื่นถ้า (ObjectWrapperFactory.hasWrapperfor (Object)) {this.ObjectWrapper = ObjectWrapperFactory.getWrapperfor (this, Object); } อื่นถ้า (วัตถุอินสแตนซ์ของวัตถุ) {this.ObjectWrapper = ใหม่ mapWrapper (สิ่งนี้, (แผนที่) วัตถุ); } else if (object instanceof collection) {this.ObjectWrapper = new CollectionWrapper (สิ่งนี้, (คอลเลกชัน) วัตถุ); } else {// สิ่งที่เรามักจะใช้คือ beanwrapper this.objectWrapper = new beanWrapper (นี่, วัตถุ); -เพื่อให้เข้าใจการแทรกซึมมากขึ้นเรายังคงติดตามและในที่สุดเราก็เรียนรู้ว่ามันจะเรียกฟังก์ชั่นตัวสร้างของคลาส Reflector
ตัวสะท้อนแสงส่วนตัว (คลาส <?> clazz) {type = clazz; // รับคลาส Constructor AddDefaultConstructor (clazz); // รับชุดเมธอด AddgetMethods (clazz); // รับชุดวิธีการตั้งค่า addsetMethods (clazz); // รับชุดคุณสมบัติภายใน addfields (clazz); ReadableProperTyNames = getMethods.keyset (). toarray (สตริงใหม่ [getMethods.keyset (). size ()]); writeablePropertyNames = setMethods.keyset (). toarray (สตริงใหม่ [setMethods.keyset (). size ()]); สำหรับ (Propname String: ReadableProperTyNames) {caseInsensenitivePropertyMap.put (propname.touppercase (locale.english), propname); } สำหรับ (Propname String: writeableProperTyNames) {caseInsensentivePropertyMap.put (propname.touppercase (locale.english), propname); - จากนี้เราสามารถรู้ได้ว่าการใช้คลาสพร็อกซีตัวสะท้อนแสงและ MetaObject คุณสามารถสำรวจคุณลักษณะทั้งหมดที่เกี่ยวข้องกับคลาสพร็อกซี ใช้คลาส RoutingStatementHandler เป็นตัวอย่าง หลังจากการดำเนินการข้างต้นคุณสามารถเข้าถึงตัวแทนคุณลักษณะภายในและแอตทริบิวต์ภายในของ configuration/objectFactory/typeHandlerRegistry/resultSetHandler/parameterHandler/mappedStatement และแอตทริบิวต์อื่น ๆ
MetaObject#getValue()
ข้างต้นอธิบายถึงวิธีการพร็อกซีคุณสมบัติภายในของคลาสพร็อกซี นอกจากนี้เรายังสามารถดูวิธีเรียกได้อย่างถูกต้อง
วัตถุสาธารณะ getValue (ชื่อสตริง) {// PropertyTokenizer คล้ายกับ StringTokenizer ยกเว้นว่าอดีตถูกเขียนเป็นตัวคั่น PropertyTokenizer prop = ใหม่ PropertyTokenizer (ชื่อ); if (prop.hasnext ()) {metaobject metavalue = metaobjectforProperty (prop.getIndexedName ()); if (metavalue == systemmetaobject.null_meta_object) {return null; } else {return metavalue.getValue (prop.getChildren ()); }} else {return objectWrapper.get (prop); - การวิเคราะห์เฉพาะจะไม่ถูกอธิบายที่นี่ วิธีการรับสตริง SQL ที่เป็นเจ้าของโดย attementHandler สามารถรับได้โดย getValue("delegate.boundSql.sql") และแอตทริบิวต์ในนั้นจะต้องเป็นคุณลักษณะภายใน
MetaObject#setValue()
หลักการเหมือนกับวิธี MetaObject#getValue()
สรุป
ด้านบนเป็นบทช่วยสอนเกี่ยวกับการใช้ปลั๊กอิน Spring Mybatis Paging ที่แนะนำโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!