ตามแนวคิดของหน้าต่อไปนี้มันเป็นเรื่องง่ายที่จะใช้การออกแบบผู้เช่าหลายคนของ mybitas
ใช้ interceptor ที่จัดทำโดย mybatis คำสั่ง SQL ที่เพจถูกประมวลผลเป็น SQLs เพจที่แตกต่างกันผ่านการห่อหุ้ม
ตัวอย่างนี้ได้ใช้ฟังก์ชั่นการปนเปื้อนของ MySQL และ Oracle ให้ความสนใจกับแพ็คเกจใบเสนอราคาต่อไปนี้และอย่าอ้างว่าไม่ถูกต้อง
นำเข้า java.sql.Connection; นำเข้า Java.sql.preparedStatement; นำเข้า java.sql.resultset; นำเข้า java.sql.sqlexception; นำเข้า java.util.list; นำเข้า java.util.properties; org.apache.ibatis.executor.statement.routingStatementHandler; นำเข้า org.apache.ibatis.executor.statement.statementhandler; นำเข้า org.apache.ibatis.mapping.boundsql; นำเข้า org.apache.atis.mapping.mapping.mapping; org.apache.ibatis.plugin.interceptor; นำเข้า org.apache.ibatis.plugin.intercepts; นำเข้า org.apache.ibatis.plugin.invocation; นำเข้า org.apache.ibatis.plugin.plugin; org.apache.ibatis.scripting.defaults.defaultparameterhandler; นำเข้า com.yidao.utils.page; นำเข้า com.yidao.utils.reflecthelper;/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * หลักการของ MyBatis Paging ถูกนำมาใช้โดยใช้ interceptors: * เพื่อใช้ JDBC เพื่อใช้งานในฐานข้อมูลคุณต้องมีวัตถุคำสั่งที่สอดคล้องกัน ก่อนที่ MyBatis จะดำเนินการคำสั่ง SQL มันจะสร้างวัตถุคำสั่งที่มีคำสั่ง SQL และคำสั่ง SQL ที่เกี่ยวข้อง* จะถูกสร้างขึ้นก่อนคำสั่งดังนั้นเราจึงสามารถเริ่มต้นด้วยคำสั่ง SQL ที่ใช้ในการสร้างคำสั่งก่อนที่จะสร้างคำสั่ง ในคำสั่ง MyBatis ถูกสร้างขึ้นโดย * วิธีการเตรียมของวัตถุ RoutingStatementHandler ดังนั้นหนึ่งในแนวคิดสำหรับการใช้ตัวดักจับเพื่อใช้ MyBatis paging คือการสกัดกั้นวิธีการเตรียมของอินเทอร์เฟซ attementhandler จากนั้นเปลี่ยนคำสั่ง SQL เป็นคำสั่ง sql การสืบค้น pagination ที่สอดคล้องกันในวิธีการสกัดกั้นแล้วเรียกใช้วิธีการเตรียมของวัตถุคำสั่ง * * สำหรับการปนเปื้อนหนึ่งในการดำเนินการที่เราต้องทำในตัวดักคือการนับจำนวนบันทึกทั้งหมดที่ตรงกับเงื่อนไขปัจจุบัน นี่คือการได้รับคำสั่ง SQL ดั้งเดิมเปลี่ยนเป็นคำสั่งทางสถิติที่สอดคล้องกันจากนั้นแทนที่พารามิเตอร์ในคำสั่ง SQL โดยใช้พารามิเตอร์ myBatis encapsulated และพารามิเตอร์ * การตั้งค่า * จากนั้นคำสั่ง SQL จะทำการสืบค้นจำนวนระเบียนจะถูกดำเนินการเพื่อนับจำนวนระเบียนทั้งหมด * */ @Intercepts ({ @signature (type = stementhandler.class, method = "เตรียม", args = {connection.class})}) คลาสสาธารณะ PageInterceptor ใช้ interceptor {private String Dialect = ""; // ฐานข้อมูลภาษาถิ่นส่วนตัว PAGESQLID = ""; // id ที่จำเป็นต้องสกัดกั้นใน mapper.xml (การจับคู่ปกติ) การสกัดกั้นวัตถุสาธารณะ (การเรียกร้องการเรียกร้อง) โยน {// มีเพียงสองคลาสการใช้งานสำหรับคำชี้แจง handler หนึ่งคือเส้นทางการกำหนดเส้นทาง handler และอื่น ๆ คือคลาสที่เป็นนามธรรม // basestatementhandler มีสามคลาสย่อยคือง่ายที่สุดในการจัดเตรียม, PreadingStatementHandler และ CallablestatementHandler // SimplestatementHandler ใช้ในการประมวลผลคำสั่ง, PreadingStatementHandler Handles PreparedStatement และ CallAblestatementHandler คือ // กระบวนการ callablestatement MyBatis สร้าง RoutingStatementHandler เมื่อประมวลผลคำสั่ง SQL ใน RoutingStatementHandler มีคุณสมบัติตัวแทนของประเภท // attementHandler ประเภท RoutingStatementHandler จะสร้าง basestatementHandler ที่สอดคล้องกันตามคำสั่งที่แตกต่างกันนั่นคือ SimplestatementHandler, // PreadingStatementHandler หรือ CallablestatementHandler ใน RoutingStatementHandler วิธีการอินเตอร์เฟสคำชี้แจงทั้งหมดจะถูกนำมาใช้โดยตัวแทนที่สอดคล้องกับตัวแทนที่เรียกว่า // เราได้ทำเครื่องหมายว่าสกัดกั้นการสกัดกั้นวิธีการเตรียมการของอินเทอร์เฟซคำสั่ง handler ด้วย @Signature ในคลาส PageInterceptor เนื่องจาก mybatis จะห่อมันผ่านวิธีการปลั๊กอิน Interceptor เมื่อสร้าง RoutingStatementHandler ดังนั้นวัตถุเป้าหมายที่เราสกัดกั้นที่นี่จะต้องเป็นวัตถุ RoutingStatementHandler if (Invocation.getTarget () อินสแตนซ์ของการกำหนดเส้นทาง StatementHandler) {routingStatementHandler attementHandler = (เส้นทางการกำหนดเส้นทาง chocation.getTarget (); คำชี้แจง handler delegate = (attementhandler) reflecthelper.getfieldValue (คำชี้แจง handler, "มอบหมาย"); BoundSQL BUNTSQL = Delegate.getBoundSQL (); Object obj = boundsql.getParameterObject (); ถ้า (OBJ Instanceof Page <?>) {หน้า <?> page = (หน้า <?>) obj; // ดึงคุณสมบัติ MappedStatement ของ BasestatementHandler ของผู้แทนระดับผู้แทนระดับ MappedStatement MappedStatement = (MappedStatement) Reflecthelper.getFieldValue (ผู้แทน, "MappedStatement"); // พารามิเตอร์ของวิธีการเตรียมการที่ถูกสกัดกั้นคือการเชื่อมต่อการเชื่อมต่อการเชื่อมต่อวัตถุการเชื่อมต่อ = (การเชื่อมต่อ) ravecocation.getArgs () [0]; // รับคำสั่ง SQL ที่ดำเนินการในปัจจุบันนั่นคือคำสั่ง SQL ที่เราเขียนโดยตรงในสตริงคำสั่ง MAPPER MAPPING SQL = BUNTSQL.GETSQL (); // ตั้งค่าจำนวนระเบียนทั้งหมดสำหรับวัตถุพารามิเตอร์หน้าปัจจุบัน this.settotalRecord (หน้า, MappedStatement, การเชื่อมต่อ); // รับสตริงคำสั่ง SQL PAGGE PAGED PAGESQL = this.getPagesQl (หน้า, SQL); // ใช้การสะท้อนกลับเพื่อตั้งค่าแอตทริบิวต์ SQL ที่สอดคล้องกับขอบเขตปัจจุบันเพื่อสร้างคำสั่ง SQL เพจที่ดีสำหรับเรา reflecthelper.setfieldValue (BoundSQL, "SQL", PagesQL); }} return invocation.proceed (); } /*** ตั้งค่าจำนวนระเบียนทั้งหมดสำหรับหน้าวัตถุพารามิเตอร์ปัจจุบัน** @param หน้าคำสั่ง Mapper Mapping* @param MappedStatement Mapping Mapping Mapping คำสั่ง* @param การเชื่อมต่อฐานข้อมูลปัจจุบันการเชื่อมต่อ* /โมฆะส่วนตัว settotalrecord (หน้า <?> หน้า ขอบเขตนี้เป็นวัตถุเดียวกับขอบเขตที่เราได้รับโดยใช้คำสั่ง handler // boundSQL ในตัวแทนยังได้รับผ่านวิธี mappedStatement.getBoundSQL (paramobj) BoundSQL BUNTSQL = MAPPEDSTATEMENT.GETBOUNDSQL (หน้า); // รับสตริงคำสั่ง SQL ที่สอดคล้องกัน sql = boundsql.getSql (); // รับคำสั่ง SQL ที่สอดคล้องกันที่คำนวณจำนวนทั้งหมดของบันทึกโดยการสอบถามคำสั่ง SQL String countsql = this.getCountSql (SQL); // รับแผนที่พารามิเตอร์ที่สอดคล้องกันผ่านรายการ boundSQL <parameterMapping> parameterMappings = boundSQL.getParameterMappings (); // ใช้การกำหนดค่า, คำสั่ง SQL CountsQL สำหรับการสืบค้นเร็กคอร์ด, พารามิเตอร์การแมปพารามิเตอร์พารามิเตอร์ความสัมพันธ์และหน้าวัตถุพารามิเตอร์เพื่อสร้างวัตถุ BoundSQL ที่สอดคล้องกับบันทึกการสืบค้น BoundSQL CountBoundSQL = New BoundSQL (MappedStatement.getConfiguration (), CountsQl, ParameterMappings, หน้า); // สร้างวัตถุพารามิเตอร์ handler สำหรับการตั้งค่าพารามิเตอร์ผ่านการแม็พสเตทเพจหน้าวัตถุพารามิเตอร์และการนับจำนวนวัตถุ BoundSQL ParameterHandler ParameterHandler = ใหม่ DefaultParameterHandler (MappedStatement, หน้า, CountBoundSQL); // สร้างวัตถุ PreparedStatement ที่สอดคล้องกับ CountsQL ผ่านการเชื่อมต่อ PreparedStatement PSTMT = NULL; ผลลัพธ์ RS = NULL; ลอง {pstmt = connection.prepareStatement (countsql); // ตั้งค่าพารามิเตอร์พารามิเตอร์สำหรับวัตถุ PreparedStatement ผ่าน ParameterHandler.SetParameters (PSTMT); // จากนั้นจะถูกดำเนินการเพื่อให้ได้จำนวนระเบียนทั้งหมดและได้รับผลลัพธ์ rs = pstmt.executeQuery (); if (rs.next ()) {int totalRecord = rs.getInt (1); // ตั้งค่าจำนวนระเบียนทั้งหมดสำหรับวัตถุหน้าพารามิเตอร์ปัจจุบัน SettotalRecord (TotalRecord); }} catch (sqlexception e) {e.printstacktrace (); } ในที่สุด {ลอง {ถ้า (rs! = null) rs.close (); if (pstmt! = null) pstmt.close (); } catch (sqlexception e) {e.printstacktrace (); }}} / ** * คำสั่ง SQL ที่ได้รับจำนวนระเบียนทั้งหมดที่สอดคล้องกันในแบบสอบถาม * @param SQL * @return * / สตริงส่วนตัว getCountSql (สตริง SQL) {int index = sql.indexof ("จาก"); return "เลือก count (*)" + sql.substring (ดัชนี); } /*** รับคำสั่ง SQL แบบสอบถาม Pagination ที่สอดคล้องกันตามวัตถุหน้า มีเพียงสองประเภทฐานข้อมูลที่ทำไว้ที่นี่ MySQL และ Oracle * ไม่มีฐานข้อมูลอื่น ๆ ที่เป็นเพจ * * @param หน้าเพจเพจเพจหน้า * @param SQL คำสั่ง SQL ดั้งเดิม * @return */ สตริงส่วนตัว getPagesQl (หน้า <?> หน้า, สตริง SQL) if ("MySQL" .EqualSignorecase (ภาษาถิ่น)) {return getMySqlPagesQl (หน้า, sqlbuffer); } อื่นถ้า ("Oracle" .equalsignorecase (ภาษาถิ่น)) {return getoraclePagesQl (หน้า, sqlbuffer); } ส่งคืน sqlbuffer.toString (); } / *** รับคำสั่ง Query Page สำหรับฐานข้อมูล mysql* @param หน้าเพจเพจวัตถุ* @param sqlbuffer stringbuffer วัตถุที่มีคำสั่ง sql ดั้งเดิม* @return mysql คำสั่ง Page ฐานข้อมูล / / / / / / / / / / / / / / / / / / / / / / / / / / / / ตำแหน่งของบันทึกใน MySQL เริ่มต้นจาก 0. // System.out.println ("หน้า:"+page.getPage ()+"--------"+page.getRows ()); int offset = (page.getPage () - 1) * page.getrows (); sqlbuffer.append ("จำกัด ") .append (ชดเชย) .append (","). ผนวก (page.getrows ()); ส่งคืน sqlbuffer.toString (); } / *** รับคำสั่ง Query Page สำหรับฐานข้อมูล Oracle* @param หน้าเพจวัตถุ* @param Sqlbuffer StringBuffer Object ที่มีคำสั่ง SQL ดั้งเดิม* @return Pagination Query คำสั่งสำหรับ Oracle Database* / Private String Oracle Pagination ดำเนินการผ่าน Rownum และ Rownum เริ่มต้นจาก 1 int offset = (page.getPage () - 1) * page.getrows () + 1; sqlbuffer.insert (0, "เลือก u.*, rownum r จาก (") .append (") u โดยที่ rownum <") .append (ออฟเซ็ต + page.getrows ()); sqlbuffer.insert (0, "เลือก * จาก (") .append (") โดยที่ r> =") .append (ออฟเซ็ต); // คำสั่ง SQL ด้านบนมีลักษณะเช่นนี้: // select * จาก (เลือก u. *, rownum r จาก (เลือก * จาก t_user) u โดยที่ rownum <31) โดยที่ r> = 16 ส่งคืน sqlbuffer.toString (); } / *** วิธีการห่อหุ้มวัตถุต้นฉบับที่สอดคล้องกับปลั๊กอิน interceptor* / วัตถุสาธารณะ (Object Arg0) {// toDo วิธีการที่สร้างขึ้นอัตโนมัติ stub ถ้า (arg0 อินสแตนซ์ของคำสั่ง handler) {return plugin.wrap (arg0, this); } else {return arg0; }} / *** ตั้งค่าคุณสมบัติเมื่อลงทะเบียน interceptor* / โมฆะสาธารณะ setProperties (คุณสมบัติ p) {} สตริงสาธารณะ getDialect () {return Dialect; } โมฆะสาธารณะ setDialect (ภาษาถิ่นสตริง) {this.dialect = ภาษาถิ่น; } สตริงสาธารณะ getPagesQlid () {return pageSqLid; } โมฆะสาธารณะ setPagesQLID (สตริง pageSQLID) {this.pagesQlid = pagesQlid; }} การกำหนดค่า XML:
<!-การกำหนดค่าการเขียนโปรแกรมส่วนต่อประสาน MyBatis-> <bean> <!-BasePackage ระบุแพ็คเกจที่จะสแกน Mappers ภายใต้แพ็คเกจนี้จะถูกค้นหา สามารถระบุแพ็คเกจหลายแพ็คเกจโดยคั่นด้วยเครื่องหมายจุลภาคหรือเครื่องหมายอัฒภาค-> <ชื่อคุณสมบัติ = "basepackage" value = "com.yidao.mybatis.dao" /> <property name = "sqlsessionfactorybeanname" value-pactiumnintion> "sqlsessionFactory" /> name = "Dialect" value = "MySQL"/> <!-สกัดกั้นคำสั่งด้วย ID ที่มีอักขระแบบสอบถามในไฟล์ mapper.xml-> <property name = "pagesqlid" value = ".*แบบสอบถาม $"/> </ebean>
ชั้นเรียน
แพ็คเกจ com.yidao.utils;/** ดูด้วยตัวคุณเองจำเป็นต้องมีฟิลด์ใดบ้างที่จะเพิ่มเข้าไปในหน้า*/ระดับสาธารณะ {แถวจำนวนเต็มส่วนตัว; หน้าจำนวนเต็มส่วนตัว = 1; TotalRecord ส่วนตัว สาธารณะจำนวนเต็ม getrows () {แถวกลับ; } โมฆะสาธารณะ setrows (แถวจำนวนเต็ม) {this.rows = rows; } Public Integer GetPage () {หน้าคืน; } public void setpage (หน้าจำนวนเต็ม) {this.page = page; } จำนวนเต็มสาธารณะ getTotalRecord () {return totalRecord; } โมฆะสาธารณะ SettotAlrecord (จำนวนเต็ม TotalRecord) {this.totalRecord = TotalRecord; - คลาส Reflecthelper
แพ็คเกจ com.yidao.utils; นำเข้า java.lang.reflect.field; นำเข้า org.apache.commons.lang3.reflect.fieldutils; คลาสสาธารณะ reflecthelper {วัตถุสาธารณะคงที่ getfieldValue (Object obj } Field TargetField = getTargetField (obj.getClass (), fieldName); ลอง {return fieldutils.readfield (Targetfield, OBJ, TRUE); } catch (unglegalAccessException e) {e.printStackTrace (); } return null; } ฟิลด์สแตติกสาธารณะ getTargetField (คลาส <?> TargetClass, String FieldName) {Field Field = NULL; ลอง {ถ้า (targetClass == null) {ฟิลด์ return; } if (object.class.equals (targetClass)) {ฟิลด์ return; } field = fieldUtils.getDeclaredField (TargetClass, FieldName, True); if (field == null) {field = getTargetField (targetClass.getSuperClass (), fieldName); }} catch (exception e) {} ฟิลด์ส่งคืน; } โมฆะคงที่สาธารณะ setFieldValue (Object OBJ, String FieldName, ค่าวัตถุ) {ถ้า (null == OBJ) {return;} Field TargetField = getTargetField (obj.getClass (), fieldName); ลอง {fieldUtils.writefield (Targetfield, OBJ, ค่า); } catch (unglegalAccessException e) {e.printStackTrace (); -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น