Punto de entrada de paginación mybatis
Hay un concepto de complementos (complementos) en MyBatis, que es esencialmente una idea de interceptor. El análisis específico se puede encontrar en la investigación sobre el principio del interceptor mybatis en otro artículo. Sobre esta base, este artículo mostrará directamente el código de implementación del proyecto real y otros análisis relacionados.
Paging Implementación de código específico
Primero podemos definir la clase de resumen del dialecto para implementar la paginación abstractDialect.java
Public Abstract Class AbstractDialect { / *** Si el límite y el desplazamiento son compatibles* @return* / public abstract Boolean SupportLimitOffset (); / ** * Si el límite es compatible * @return */ public abstract boolean supportLimit (); / ** * Obtenga SQL después de agregar atributos de paginación * @param sql * @param offset * @param limit * @return */ public abstract String getLimitString (String SQL, int Offset, int Limit);}Además, implementaremos la tecnología de paginación de página de Oracle y MySQL Database por separado.
Mysqldialect.java-mysql dialecto de paginación
public class mySqlDialect extiende AbstractDialect {public Boolean SupportSlimitOffset () {return true; } public boolean SupportSlimit () {return true; } public String getLimitString (string sql, int offset, int limit) {if (offset> 0) {return sql + "limit" + offset + "," + limit; } else {return sql + "límite" + límite; }}}Oracledialect.Java-Oracle Dialect Implementation
Public Class Oracledialect extiende Adialect {@Override public boolean SupportLimitOffset () {return false; } @Override public boolean supportLimit () {return false; } @Override public String getLimitString (String Sql, int Start, int Limit) {if (start <0) {start = 0; } if (límite <0) {limit = 10; } StringBuilder Pagesql = new StringBuilder (100); pagesql.append ("Seleccionar * de (seleccione temp. *, Rownum Row_id desde ("); Pagesql.Append (SQL); Pagesql.Append (") TEMP WHERE ROWNUM <=") .Append (Start+Limit); Pagesql.Append (") Where Row_id>") .Append (inicio); return pagesql.ToString (); }}La correspondiente implementación del interceptor de complemento MyBatis es la siguiente: Intercept DeclaryHandler#Prepare (Connection Con) para crear el método de objeto de instrucción SQL
PaginationInterceptor.java
@Intercepts ({@Signature (type = DecltationHandler.class, método = "Preparar", args = {Connection.Class})}) public Final Clase PagationInterceptor implementa Interceptor {private final de logger estatic log = loggerFactory .getLogger (paginationInterceptor.classs); dialecto de adialecto privado; public void setDialect (dialecto adialect) {this.dialect = dialect; } @Override Public Object Intercept (Invocation Invocation) lanza lanzar {// Obtener directamente el objeto interceptado, que implementa la enrutamiento de clases StatementHandler DeclarationHandler DeclarationHandler = (DeclarationHandler) Invocation .GetTarget (); BoundSQL Boundsql = DeclaryHandler.getBoundSql (); // Obtener metaobject, utilizado principalmente para obtener el objeto y los atributos asociados con el metaobject metaObject MetaStatementHandler de metaObject de Declaration = metaObject.forObject (DeclarationHandler, New DefaultObjectFactory (), New DefaultWetWrapperFactory ()); MappedStatement MappedStmt = (MappedStatement) MetastatementHandler .getValue ("Delegate.MappedStatement" .intern ()); // solo pagine el método de QueryPagination () if (mappedstmt.getID (). IndexOf ("QueryPagination") ==-1) {return invocation.proced (); } // Reconstruye la cadena SQL de Paging Originalsql = (String) MetastatementHandler .getValue ("delegate.boundsql.sql" .intern ()); metastatementHandler.setValue ("delegate.boundsql.sql" .intern (), dialect .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 ("página sql:" + boundsql.getsql ()); return invocation.proced (); } // Interception Object @Override Public Object Plugin (Object Target) {return Plugin.wrap (Target, este); } @Override public void setProperties (propiedades de propiedades) {}}La configuración XML correspondiente de Spring puede ser la siguiente, tomando Oracle Pagination como ejemplo
*
Use el código y la configuración anteriores para completar la operación de paginación de la base de datos Oracle y la base de datos MySQL. Y el blogger analiza uno de los puntos
MyBatis#Análisis de objetos metaobject-metadata
Cuando el blogger usó el código anterior, la clase Metaobject lo desconcertó. Puede obtener directamente todas las propiedades asociadas del objeto proxyed a través del método getValue (). Podemos seguir el código fuente para aprender más
MetaObject#forObject()
Todos los objetos proxy ingresan a través de este método estático
public static metaObject forObject (objeto objeto, objectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {if (object == null) {return SystemmetaObject.null_meta_object; } else {return new MetaObject (object, ObjectFactory, ObjectWrapperFactory); }}Podemos observar directamente el constructor, aquí está el misterio
MetaObject privado (objeto objeto, ObjectFactory ObjectFactory, ObjectWrapperFactory ObjectSwrapperFactory) {this.originalObject = object; this.ObjectFactory = ObjectFactory; this.ObjectWrapperFactory = ObjectRapperFactory; // Todas las adquisiciones de atributos se obtienen a través de la clase ObjectWrapper. Aquí, juzgamos principalmente el tipo de objeto de objeto que está proxyed if (object OnstoneOf ObjectWrapper) {this.ObjectWrapper = (ObjectWrapper) Object; } else if (objectWrapperFactory.haswrapperfor (object)) {this.ObjectWrapper = ObjectWrapperFactory.getWrapperfor (this, Object); } else if (objeto instanciaf map) {this.ObjectWrapper = new MapWrapper (this, (map) objeto); } else if (objeto instancia de colección) {this.ObjectWrapper = new CollectionWrapper (this, (colección) objeto); } else {// Lo que usamos a menudo es beanwrapper this.ObjectWrapper = new BeanWrapper (this, Object); }}Para comprender más infiltrado, continuamos haciendo un seguimiento, y finalmente aprendimos que llamará a la función del constructor de la clase Reflector
privado reflector (clase <?> clazz) {type = clazz; // Obtener la clase Constructor AddFaultConstructor (Clazz); // Obtener el método Get Set AddGetMethods (Clazz); // Obtener el método establecido establecer AddSetMethods (Clazz); // Obtener el conjunto de propiedades internos AddFields (Clazz); ReadablePropertynames = getMethods.KeySet (). ToArray (nueva cadena [getMethods.KeySet (). size ()]); WriteablePropertynames = setMethods.KeySet (). ToArray (nueva cadena [setMethods.KeySet (). size ()]); for (string propName: readablePropertynames) {caseInsensitivePropertyMap.put (propName.ToUpperperCase (locale.English), propname); } for (string propName: writeablePropertynames) {caseInsensitivePropertyMap.put (propName.ToUpperperCase (locale.English), propName); }} A partir de esto, podemos saber que utilizando la clase de proxy de reflector y el metaobjecto, puede atravesar todos los atributos asociados con la clase proxy. Tome RoutingStatementHandler como ejemplo. Después de la operación anterior, puede acceder al delegado de atributo interno y a los atributos internos de la configuration/objectFactory/typeHandlerRegistry/resultSetHandler/parameterHandler/mappedStatement y otros atributos.
MetaObject#getValue()
Lo anterior explica cómo proxy de las propiedades internas de la clase proxy. También podemos echar un vistazo a cómo llamarlo correctamente.
Public Object getValue (nombre de cadena) {// PropertyTokenizer es similar a StringTokenizer, excepto que el primero está escrito como delimitador PropertyTokenizer prop = New PropertyTokenizer (nombre); 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); }} El análisis específico no se explicará aquí. Cómo obtener la cadena SQL propiedad de DeclaryHandler se puede obtener mediante getValue("delegate.boundSql.sql") y los atributos en ella deben ser atributos internos (sensibles a la caja).
MetaObject#setValue()
El principio es el mismo que MetaObject#getValue()
Resumir
Lo anterior es el tutorial sobre el uso de Spring MyBatis Paging Plug-in presentado por el editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!