หมายเหตุ: บล็อกนี้แตกต่างจากปลั๊กอินเพจปัจจุบันอย่างสิ้นเชิงดังนั้นขอแนะนำให้คุณตรวจสอบซอร์สโค้ดและเอกสารล่าสุดผ่านที่อยู่โครงการด้านบนเพื่อทำความเข้าใจ
ฉันกังวลเกี่ยวกับการสืบค้นการปนเปื้อนของ mybatis มาก่อนและฉันได้ค้นหาบทความที่เกี่ยวข้องหลายอย่างออนไลน์ แต่ฉันไม่ได้ใช้บทความสุดท้าย สถานที่เพจถูกเขียนด้วยลายมืออย่างสมบูรณ์ด้วย SQL และ Count SQL ซึ่งเป็นปัญหามาก
ต่อมาในขณะที่ฉันต้องการเขียนการติดอันดับจากภายใน mybatis ฉันเขียนการใช้งานสำหรับ LanguagedRiver ไม่มีปัญหาเกี่ยวกับการปนเปื้อนอัตโนมัติ แต่จำนวนการสืบค้นทั้งหมด (นับ) ยังไม่สามารถแก้ไขได้ในครั้งเดียวและมันก็ยังไม่ได้รับการแก้ไข
เมื่อเร็ว ๆ นี้ฉันต้องใช้การปนเปื้อนอีกครั้ง เพื่อความสะดวกฉันต้องเขียนคลาสการแบ่งหน้าทั่วไปดังนั้นฉันจึงอ้างถึงรหัสการปนเปื้อน mybatis ส่วนใหญ่บนอินเทอร์เน็ตอีกครั้ง
ในความเป็นจริงนานมาแล้วมีคนเปิดการใช้งานแหล่งที่มาของ GitHub สนับสนุน MySQL, Oracle และ SQLServer ซึ่งคล้ายกับการอ้างอิงข้างต้นและมีการพิจารณาที่ครอบคลุมมากขึ้น แต่ฉันคิดว่าชั้นเรียนมากเกินไปมีปัญหาเกินไปดังนั้นฉันจึงใช้ชั้นเรียนที่มีการสกัดกั้นเพียงครั้งเดียวซึ่งสามารถแบ่งออกเป็นสองคลาสได้ หนึ่งในชั้นเรียนถูกเขียนเป็นชั้นเรียนคงที่โดยฉันและวางไว้ในตัวดัก คุณยังสามารถแยกคลาสหน้าเพื่ออำนวยความสะดวกในการใช้หน้า
มาพูดคุยเกี่ยวกับวิธีการใช้งานก่อน ปลั๊กอินนี้มีคลาสเดียวเท่านั้น: pagehelper.java
ลายเซ็น interceptor คือ:
@Intercepts ({ @signature (type = stementhandler.class, method = "เตรียม", args = {connection.class}), @signature (type = resultsethandler.class, method = "handleresultsets", args = {statement.class})})ลายเซ็นที่นี่มีความสำคัญต่อการใช้งานและแนวคิดทั้งหมด ก่อนอื่นฉันสกัดกั้นวิธีการเตรียมการเพื่อเปลี่ยนการแบ่งหน้า SQL และทำเคียวรีนับ จากนั้นฉันก็สกัดกั้นวิธีการ HandlerEsultSets เพื่อรับผลการประมวลผลครั้งสุดท้ายและใส่ผลลัพธ์ลงในวัตถุหน้า
ต่อไปนี้เป็นรหัสเพื่อแก้ไขหน้าซึ่งเป็นการปรับเปลี่ยนสำหรับข้อมูล Oracle หากคุณใช้ฐานข้อมูลอื่น ๆ คุณสามารถแก้ไขรหัสได้ที่นี่ด้วยตัวคุณเอง
/ ** * แก้ไข SQL ดั้งเดิมเป็น pagination SQL * @Param SQL * @param หน้า * @return */ สตริงส่วนตัว buildpagesql (สตริง SQL, หน้าหน้า) {StringBuilder PagesQl = StringBuilder ใหม่ (200); PagesQl.Append ("เลือก * จาก (เลือกอุณหภูมิ *, rownum row_id จาก ("); pagesql.append (sql); pagesql.append (") อุณหภูมิที่ rownum <=") return pagesql.toString (); - จากนั้นในเมธอด setPageParameter ต่อไปนี้จำเป็นต้องแก้ไขคำสั่ง SELECT COUNT
// จำนวนทั้งหมดของบันทึกสตริง countsql = "เลือกนับ (0) จาก (" + sql + ")";ทำไมฉันไม่ให้การสนับสนุนฐานข้อมูลต่างๆ ฉันไม่คิดว่ามันจำเป็น ฐานข้อมูลบางอย่างไม่รองรับการเพจและปลั๊กอินนี้ง่ายขึ้นเท่าไหร่ก็ยิ่งง่ายขึ้นสำหรับนักพัฒนาซอฟต์แวร์ที่จะเข้าใจและแก้ไข การปรับเปลี่ยนเป็นแบบสอบถามการปนเปื้อนที่คุณต้องการไม่ใช่ปัญหาอย่างแน่นอน
ในที่สุดรหัสที่สมบูรณ์จะถูกเพิ่ม (อ่านต่อไปนอกจากนี้ยังมีวิธีการใช้งานด้านล่าง): (คลิกเพื่อดาวน์โหลด)
แพ็คเกจ com.mybatis.util; นำเข้า org.apache.ibatis.executor.parameter.parameterhandler; นำเข้า org.apache.ibatis.executor.resultset.resultsethandler; นำเข้า org.apache.ibatis.executor.statement.statementhandler; นำเข้า org.apache.ibatis.mapping.boundsql; นำเข้า org.apache.ibatis.mapping.mappedstatement; นำเข้า org.apache.ibatis.plugin.*; นำเข้า org.apache.ibatis.reflection.metaobject; นำเข้า org.apache.ibatis.reflection.systemmetaobject; นำเข้า org.apache.ibatis.scripting.defaults.defaultparameterhandler; นำเข้า org.apache.log4j.logger; นำเข้า Java.sql.*; นำเข้า java.util.list; นำเข้า java.util.properties; /*** mybatis-สกัดกั้นการปนเปื้อนสากล* @author liuzh/abel533/isea* สร้างโดย liuzh เมื่อวันที่ 14-4-15 */ @Intercepts ({ @signature (type = stementhandler.class, method = "prepect", args = {connection.class}), @signature (type = resultsethandler.class, method = "handleresultsets", args = {statement.class}) logger.getLogger (pagehelper.class); public Static Final ThreadLocal <Page> localPage = ใหม่ ThreadLocal <page> (); / ** * เริ่มต้นเพจ * @param pagenum * @param PageSize */ Public Static Void startpage (int pagenum, หน้า int) {localPage.set (หน้าใหม่ (pagenum, pagesize)); } /*** สิ้นสุดการเพจและส่งคืนผลลัพธ์ วิธีการที่จะต้องเรียกมิฉะนั้น localPage จะถูกบันทึกไว้จนกว่าจะถึงหน้าเริ่มต้น * @return */ หน้าคงที่สาธารณะ endpage () {หน้าหน้า = localPage.get (); LocalPage.remove (); หน้ากลับ; } @Override การสกัดกั้นวัตถุสาธารณะ (การเรียกร้องการเรียกใช้) โยน throwable {if (localPage.get () == null) {return invocation.proceed (); } if (Invocation.getTarget () Instanceof attementHandler) {attementHandler statementler = (คำสั่ง handler) rachation.getTarget (); metaobject metastatementhandler = systemmetaobject.forobject (attementhandler); // แยกห่วงโซ่วัตถุพร็อกซี (เนื่องจากคลาสเป้าหมายอาจถูกดักจับด้วยตัวดักหลายตัวพร็อกซีหลายตัวจะเกิดขึ้นและสองลูปต่อไปนี้ // คลาสเป้าหมายดั้งเดิมที่สุดสามารถแยกออกได้) ในขณะที่ (metastatementhandler.hasgetter ("h") {วัตถุวัตถุ = metastatementler.getValue MetastatementHandler = SystemMetaObject.forObject (วัตถุ); } // คลาสเป้าหมายที่แยกวัตถุพร็อกซีสุดท้ายในขณะที่ (metastatementhandler.hasgetter ("เป้าหมาย")) {object object = metastatementler.getValue ("เป้าหมาย"); MetastatementHandler = SystemMetaObject.forObject (วัตถุ); } MappedStatement MappedStatement = (MappedStatement) MetastatementHandler.getValue ("Delegate.MappedStatement"); // ข้อมูลหน้าถ้า (localPage.get ()! = null) {หน้าหน้า = localPage.get (); BoundSQL BUNTSQL = (BUNTSQL) MetastatementHandler.getValue ("Delegate.boundsql"); // พารามิเตอร์หน้าเป็นคุณสมบัติของพารามิเตอร์พารามิเตอร์พารามิเตอร์ SQL = boundSQL.GetSQL (); // rewrite SQL สตริง pagesql = buildPagesQl (sql, page); // rewrite paging sql metastatementhandler.setValue ("delegate.boundsql.sql", pagesql); การเชื่อมต่อการเชื่อมต่อ = (การเชื่อมต่อ) ravecocation.getArgs () [0]; // รีเซ็ตจำนวนหน้าทั้งหมดในพารามิเตอร์การเพจ ฯลฯ setPageParameter (SQL, การเชื่อมต่อ, การแม็พสเตรต, boundSQL, หน้า); // ส่งมอบสิทธิ์ในการดำเนินการไปยัง Interceptor return return.proceed (); } อื่นถ้า (Invocation.getTarget () อินสแตนซ์ของ ResultsEthandler) {object result = invocation.proceed (); หน้าหน้า = localPage.get (); page.setResult ((รายการ) ผลลัพธ์); ผลการกลับมา; } return null; } / ** * สกัดกั้นเพียงสองประเภทของ * attementHandler * ResultsEthandler * @param เป้าหมาย * @return * / @Override ปลั๊กอินวัตถุสาธารณะ (เป้าหมายวัตถุ) {ถ้า (เป้าหมายอินสแตนซ์ของคำสั่ง || อินสแตนซ์เป้าหมายของผลลัพธ์ที่ได้) {return plugin.wrap } else {return target; }} @Override โมฆะสาธารณะ setProperties (คุณสมบัติคุณสมบัติ) {} / ** * แก้ไข SQL ดั้งเดิมเป็น pagination sql * @param sql * @param หน้า * @return * / สตริงส่วนตัว buildpagesql PagesQl.Append ("เลือก * จาก (เลือกอุณหภูมิ *, rownum row_id จาก ("); pagesql.append (sql); pagesql.append (") อุณหภูมิที่ rownum <=") return pagesql.toString (); } / ** * รับจำนวนระเบียนทั้งหมด * @param sql * @param การเชื่อมต่อ * @param mappedStatement * @param boundsql * @param หน้า * / โมฆะส่วนตัว setPageParameter (สตริง SQL, การเชื่อมต่อ mappedStatement sql + ")"; PreparedStatement CountStmt = NULL; ผลลัพธ์ RS = NULL; ลอง {countStmt = connection.prepareStatement (countsql); BoundSQL COUNTBS = New BoundSQL (MappedStatement.getConfiguration (), CountsQl, BoundSQL.GetParameterMappings (), BoundSQL.GetParameterObject ()); SetParameters (CountStmt, MappedStatement, Countbs, BoundSQL.GetParameterObject ()); rs = countstmt.executeQuery (); int totalCount = 0; if (rs.next ()) {totalCount = rs.getInt (1); } page.settotal (รวม); int totalPage = totalCount / page.getPagesize () + ((TotalCount % page.getPagesize () == 0)? 0: 1); page.setPages (TotalPage); } catch (sqlexception e) {logger.error ("ละเว้นข้อยกเว้นนี้", e); } ในที่สุด {ลอง {rs.close (); } catch (sqlexception e) {logger.error ("ละเว้นข้อยกเว้นนี้", e); } ลอง {countstmt.close (); } catch (sqlexception e) {logger.error ("ละเว้นข้อยกเว้นนี้", e); }}} / ** * ค่าพารามิเตอร์ทดแทน * @param ps * @param mappedStatement * @param boundsql * @param พารามิเตอร์ * @throws sqlexception * / โมฆะส่วนตัว setParameters (paredStatement PS, mapedStatement ใหม่ DefaultParameterHandler (MappedStatement, ParameterObject, BoundSQL); ParameterHandler.SetParameters (PS); } / ** * คำอธิบาย: Pagination * ผู้แต่ง: liuzh * อัปเดต: liuzh (2014-04-16 10:56) * / หน้าคลาสคงที่สาธารณะ <E> {ส่วนตัว int pagenum; หน้า int ส่วนตัว; Statrow int ส่วนตัว; INT Endrow ส่วนตัว; รวมส่วนตัวทั้งหมด; หน้า int ส่วนตัว; รายการส่วนตัว <E> ผลลัพธ์; หน้าสาธารณะ (int pagenum, หน้า int) {this.pagenum = pagenum; this.pageize = pageSize; this.startrow = pagenum> 0? (pagenum - 1) * หน้า: 0; this.endrow = pagenum * pagesize; } รายการสาธารณะ <e> getResult () {ผลตอบแทน; } โมฆะสาธารณะ setResult (รายการ <e> ผลลัพธ์) {this.result = ผลลัพธ์; } public int getPages () {หน้ากลับ; } public void setpages (หน้า int) {this.pages = หน้า; } public int getEndrow () {return endrow; } โมฆะสาธารณะ setEndrow (int endrow) {this.endrow = endrow; } public int getPagenum () {return pagenum; } โมฆะสาธารณะ setpagenum (int pagenum) {this.pagenum = pagenum; } public int getPagesize () {กลับ pageSize; } โมฆะสาธารณะ setPagesize (int pageize) {this.page.ize = pageSize; } public int getStartrow () {return startrow; } โมฆะสาธารณะ setStartrow (int startrow) {this.startrow = startrow; } สาธารณะยาว getTotal () {ผลตอบแทนทั้งหมด; } โมฆะสาธารณะ settotal (รวมยาว) {this.total = total; } @Override สตริงสาธารณะ toString () {return "หน้า {" + "pagenum =" + pagenum + ", pagesize =" + pagesize + ", startrow =" + startrow + ", endrow =" + endrow + ", ทั้งหมด =" ทั้งหมด + ", หน้า =" - ในการใช้ interceptor นี้คุณต้องกำหนดค่า interceptor ในการกำหนดค่า MyBatis:
<plugins> <plugin interceptor = "com.mybatis.util.pagehelper"> </plugin> </plugins>
เมื่อกำหนดค่าการสกัดกั้นคุณต้องใส่ใจกับตำแหน่งของปลั๊กอิน ลำดับของปลั๊กอินมีดังนี้:
คุณสมบัติ?, การตั้งค่า?, typealiases?, typeHandlers?, ObjectFactory?, ObjectWrapperFactory?, ปลั๊กอิน?, สภาพแวดล้อม?, DatabaseidProvider?
ในที่สุดก็มีรหัสตัวอย่าง (เลเยอร์บริการ) ที่เรียกวิธีนี้:
@Override pageHelper.Page <SyslogInLog> findSySlogInLog (สตริงล็อกอิกสตริงชื่อผู้ใช้สตริง logIndate สตริงออกจากระบบ, string logerr, int pagenumber, หน้า int) โยน BusinessException sysloginlogmapper.findsysloginlog (loginiP, ชื่อผู้ใช้, logindate, exitdate, logerr); ส่งคืน pagehelper.endpage (); -
จากด้านบนเราจะเห็นว่าการใช้ปลั๊กอินนี้ง่ายมาก คุณจะต้องใช้วิธี startpage และ endpage ของ PageHelper ก่อนและหลังการสืบค้น ผลลัพธ์การโทรของรหัสกลางมีอยู่แล้วในผลลัพธ์ของ PageHelper หากคุณเรียก PageHelper ในสถานที่ที่ส่งคืนผลลัพธ์ผลลัพธ์ที่ส่งคืนยังคงเป็นรายการและคุณสามารถใช้ค่าแรก (ฉันคิดว่าไม่มีใครจะใช้มันเช่นนี้ในสถานที่นี้แน่นอนว่าไม่มีข้อผิดพลาดในลักษณะนี้)
นอกจากนี้รหัส mybatis ทั้งหมดระหว่าง startpage และ endpage จะถูก paginated และ pagehelper จะรักษาผลลัพธ์สุดท้ายเท่านั้น ดังนั้นเมื่อใช้งานคุณต้องตรวจสอบให้แน่ใจว่ามีการสอบถาม MyBatis เพียงครั้งเดียวในแต่ละครั้ง หากมีหลายเพจโปรดใช้ startpage และ endpage หลายครั้ง
เนื่องจากมีเพียงการใช้งาน Oracle เท่านั้นที่มีให้ที่นี่ฉันหวังว่าผู้อ่านที่อ้างถึงฐานข้อมูลอื่น ๆ ที่นำมาใช้โดยปลั๊กอินเพจนี้ยังสามารถเปิดแหล่งข้อมูลที่เกี่ยวข้องได้
ที่อยู่โครงการ: http://xiazai.vevb.com/201612/yuanma/mybatis_pagehelper_jb51.zip
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น