Nota: Este blog es completamente diferente del complemento de paginación actual, por lo que se recomienda que verifique el último código fuente y la documentación a través de la dirección del proyecto anterior para comprender.
He estado preocupado por la consulta de paginación mybatis antes, y he buscado muchos artículos relacionados en línea, pero no usé el último. El lugar paginado está completamente escrito a mano con SQL y Count SQL, lo cual es muy problemático.
Más tarde, por un tiempo, quería escribir una implementación de paginación desde MyBatis. Escribí una implementación para Languaged River. No hay problema con la paginación automática, pero el número total de consultas (recuento) aún no se puede resolver al mismo tiempo, y se dejó sin resolver.
Recientemente, tengo que usar la paginación nuevamente. En aras de la conveniencia, tengo que escribir una clase de paginación general, por lo que me refiero a la mayoría de los códigos de paginación mybatis nuevamente en Internet.
De hecho, hace mucho tiempo, alguien abrió la implementación de la fuente en GitHub, apoyando a MySQL, Oracle y SQLServer, que es similar a la referencia anterior y tiene una consideración más completa. Pero creo que demasiadas clases son demasiado problemáticas, por lo que implementé una clase con un solo interceptor, que en realidad se puede dividir en dos clases. Una de las clases fue escrita como una clase estática por mí y colocada en el interceptor. También puede extraer la clase de página para facilitar el uso de la página.
Hablemos primero sobre el método de implementación. Este complemento tiene solo una clase: Pagehelper.java
La firma del interceptor es:
@Intercepts ({ @firature (type = DeclettHandler.class, Method = "Prepare", args = {Connection.class}), @Signature (type = ResultSetHandler.class, método = "HandleLeSultSets", args = {Declarat.Class})})La firma aquí es crucial para toda la implementación e idea. Primero, intercepto el método de preparación para cambiar el Pagination SQL y cuento la consulta. Luego intercepto el método HandLerEdSets para obtener el último resultado de procesamiento y poniendo el resultado en el objeto de página.
El siguiente es el código para modificar la página, que es una modificación para los datos de Oracle. Si usa otras bases de datos, puede modificar el código aquí usted mismo.
/ ** * Modifique el SQL original a Pagination SQL * @param sql * @param página * @return */ private string buildPagesql (string sql, página página) {StringBuilder Pagesql = new StringBuilder (200); PAGEQL.Append ("Seleccionar * de (Seleccione temp. *, ROWNUM ROW_ID DESDE ("); PAGEQL.Append (SQL); Pagesql.Append (") TEMP WHERE ROWNUM <=") .Append (Page.getEndrow ()); Pagesql.Append (") Where_id>") .Append (page.getStarTrow ()); return pagesql.ToString (); } Luego, en el siguiente método setPageParameter, una instrucción SELECT de recuento debe modificarse de acuerdo con el tipo de base de datos:
// Número total de registros String CountSql = "Seleccionar recuento (0) desde (" + SQL + ")";¿Por qué no proporciono soporte para varias bases de datos? No creo que sea necesario. Algunas bases de datos no admiten la paginación, y cuanto más simple es este complemento, más fácil es para los desarrolladores comprender y modificar. Modificarlo en la consulta de paginación que necesita definitivamente no es un problema.
Finalmente, se agrega el código completo (continúe leyendo, también está el método de uso a continuación): (haga clic para descargar)
paquete com.mybatis.util; importar org.apache.ibatis.executor.parameter.parameterhandler; importar org.apache.ibatis.executor.resultset.resultsethandler; importar org.apache.ibatis.executor.statement.statementHandler; importar org.apache.ibatis.mapping.boundsql; importar org.apache.ibatis.mapping.MappedStatement; importar org.apache.ibatis.plugin.*; importar org.apache.ibatis.REFLECTION.MetaObject; importar org.apache.ibatis.REflection.SystemMetaObject; importar org.apache.ibatis.scripting.default.defaultParameterHandler; importar org.apache.log4j.logger; import java.sql.*; import java.util.list; import java.util.properties; /*** MyBatis-Interceptor de paginación universal* @author liuzh/abel533/isea* creado por Liuzh el 14-4-15. */ @Intercepts ({ @firature (type = stattleHandler.class, método = "preparar", args = {conecte.class}), @signature (type = resultados de resultados de resultados, método = "handleLerSultSets", args = {stattle.class})}) Public PageHelper implementa el interceptor {logger estatic logger estatic logger = privado Logger.getLogger (pageHelper.class); public static final ThreadLocal <page> localPage = new ThreadLocal <page> (); / ** * Comience a paginar * @param pagenum * @param páginas */ public static void startPage (int pagenum, int pageSize) {localPage.set (nueva página (pagenum, pageSize)); } /*** Finalice la paginación y devuelva el resultado. Se debe llamar al método, de lo contrario, localPage se guardará hasta la próxima página de inicio * @return */ public static page endPage () {página página = localPage.get (); localPage.remove (); página de regreso; } @Override Public Object Intercept (Invocation Invocation) lanza Throwable {if (localPage.get () == NULL) {return invocation.proceed (); } if (invocation.getTarget () instanceOf DeclaryHandler) {DeclarationHandler DeclarationHandler = (DeclarationHandler) Invocation.GetTarget (); Metaobject metaStatementHandler = systemmetaObject.forObject (DeclaryHandler); // Separe la cadena de objetos proxy (porque la clase de destino puede ser interceptada por múltiples interceptores, se forma múltiples proxyerización y los siguientes dos bucles // La clase de destino más primitiva puede separarse) mientras (MetastatementHandler.hasgetter ("H")) {Object = MetastatementHandler.getValue ("H"); metastatementHandler = systemmetaObject.forObject (objeto); } // La clase de destino que separa el último objeto proxy mientras (metastatementHandler.hasgetter ("target")) {object object = metastatementHandler.getValue ("target"); metastatementHandler = systemmetaObject.forObject (objeto); } MappedStatement MappedStatement = (MappedStatement) MetastatementHandler.getValue ("Delegate.MappedStatement"); // Información de la página if (localPage.get ()! = NULL) {página página = localPage.get (); BoundSQL Boundsql = (BoundSQL) metastatementHandler.getValue ("delegate.boundsql"); // Parámetro de página como una propiedad de ParameterObject ParameterString sql = Boundsql.getSql (); // reescribe sql string páginasql = buildPagesql (SQL, página); // Reescribe la paginación SQL MetastatementHandler.SetValue ("delegate.boundsql.sql", páginasql); Conexión Connection = (Connection) Invocat.GetArgs () [0]; // Restablecer el número total de páginas en los parámetros de paginación, etc. setPageParameter (SQL, Connection, MappedStatement, BoundSQL, página); // Entregue los derechos de ejecución al próximo Interceptor Devocation Invoced.proced (); } else if (invocation.getTarget () instancia de resultados) {objeto resultado = invocation.proced (); Página página = localPage.get (); Page.SetResult ((List) Resultado); resultado de retorno; } return null; } / ** * Solo intercepta estos dos tipos de * DeclarationHandler * ResultSethandler * @param Target * @return * / @Override Public Object Plugin (Object Target) {if (Target OutstoneOf DeclarationHandler || Target OptionOnsultEthandler) {return Plugin.wrap (Target, este); } else {Target de retorno; }} @Override public void setProperties (propiedades de propiedades) {} / ** * Modifique el sql original a paginación sql * @param sql * @param página * @return * / private string buildPagesql (string sql, página de página) {cadenaBuilder Pagesql = new StringBuilder (200); PAGEQL.Append ("Seleccionar * de (Seleccione temp. *, ROWNUM ROW_ID DESDE ("); PAGEQL.Append (SQL); Pagesql.Append (") TEMP WHERE ROWNUM <=") .Append (Page.getEndrow ()); Pagesql.Append (") Where_id>") .Append (page.getStarTrow ()); return pagesql.ToString (); } / ** * Obtenga el número total de registros * @param sql * @param conexión * @param mappedStatement * @param boundsql * @param página * / private void setPageParameter (string sql, conexión conexión, mappedStatement mappedStatement, boundsql boundsql, página de página) {// número total de registros de registro de cuenta sql + ")"; Preparado en cuenta CountStmt = null; ResultSet rs = null; intente {countStmt = Connection.PrepareStatement (CountSql); Boundsql CountBs = new BoundSQL (MappedStatement.getConfiguration (), CountSql, BoundSql.getParametermappings (), BoundSql.getParametRangject ()); setParameters (CountStmt, MappedStatement, Countbs, Boundsql.getParametreEpject ()); rs = countstmt.executeQuery (); int totalCount = 0; if (rs.next ()) {totalCount = rs.getInt (1); } Page.settotal (TotalCount); int TotalPage = TotalCount / Page.getPageSize () + ((TotalCount % Page.getPageSize () == 0)? 0: 1); Page.SetPages (TotalPage); } catch (sqlexception e) {logger.error ("ignorar esta excepción", e); } finalmente {try {rs.close (); } catch (sqlexception e) {logger.error ("ignorar esta excepción", e); } try {countstmt.close (); } catch (sqlexception e) {logger.error ("ignorar esta excepción", e); }} Ial DefaultParameterHandler (MappedStatement, ParameterObject, BoundSQL); ParameterHandler.SetParameters (PS); } / ** * Descripción: Pagination * Autor: Liuzh * Actualización: Liuzh (2014-04-16 10:56) * / Página de clase estática pública <E> {private int pagenum; Página privada int; privado int startrow; privado int Endrow; Privado total largo; Páginas privadas int; Resultado de la lista privada <E>; Página pública (int pagenum, int pageSize) {this.pagenum = pagenum; this.pagesize = PageSize; this.startrow = pagenum> 0? (Pageno - 1) * PageSize: 0; this.endrow = Pagenum * PageSize; } Lista pública <E> getResult () {return resultado; } public void setResult (list <E> resultado) {this.result = resultado; } public int getPages () {return Pages; } public void setPages (int páginas) {this.pages = páginas; } public int getendrow () {return EndRow; } public void setEdrow (int endrow) {this.endrow = endrow; } public int getPagenum () {return pagenum; } public void setPagenum (int pagenum) {this.pagenum = pagenum; } public int getPageSize () {return PageSize; } public void setPageSize (int págsagesize) {this.pagesize = pageSize; } public int getStarTrow () {return starTrow; } public void setStarTrow (int starTrow) {this.starTrow = starTrow; } public Long GetTotal () {return Total; } public void settotal (largo total) {this.total = total; } @Override public string toString () {return "page {" + "pagenum =" + pagenum + ", pageSize =" + pageSize + ", starTrow =" + starTrow + ", endrow =" + endrow + ", total =" + total + ", paginas =" + páginas + '}'; }}} Para usar este interceptor, primero debe configurar el interceptor en la configuración de MyBatis:
<glugins> <plugin interceptor = "com.mybatis.util.pagehelper"> </glugin> </glugins>
Al configurar un interceptor, debe prestar atención a la ubicación de los complementos. El orden de los complementos es el siguiente:
¿Propiedades?, ¿Configuración?, ¿Typealiases?, TypeHandlers?, ObjectFactory?, ObjectwrapperFactory?, complementos?, entornos?, DatabaseIdProvider?, ¿Mapeadores?
Finalmente, existe el código de ejemplo (capa de servicio) que llama a este método:
@Override public PageHelper.Page <SloginLog> FindSysLogInlog (String Loginip, String UserName, String LogIndate, String ExitDate, String LogErrer, int PageNumber, int PageSize) lanza BusinessException {pageHelper.Startpage (pagenumber, Pagesize); sysloginlogmapper.findsysloginlog (loginip, nombre de usuario, logindate, exitdate, logerr); return pageHelper.endPage (); }De lo anterior, podemos ver que usar este complemento es muy simple. Solo necesita usar los métodos de página de inicio y de página final de PageHelper antes y después de la consulta. El resultado de la llamada del código intermedio ya existe en el resultado de PageHelper. Si llama a PageHelper en un lugar que devuelve un resultado, el resultado devuelto sigue siendo una lista, y puede tomar el primer valor (creo que nadie lo usará así en este lugar, por supuesto, no hay error de esta manera).
Además, todos los códigos mybatis entre StartPage y FinPage serán paginados, y PageHelper solo conservará el último resultado. Por lo tanto, al usarlo, debe asegurarse de que solo una consulta de mybatis se ejecute en él a la vez. Si hay múltiples paginas, use StartPage y End Page varias veces.
Dado que solo se proporcionan implementaciones de Oracle aquí, espero que los lectores que se refieren a otras bases de datos implementadas por este complemento de paginación también puedan abrir el código correspondiente.
Dirección del proyecto: http://xiazai.vevb.com/201612/yuanma/mybatis_pagehelper_jb51.zip
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.