Ponto de entrada de paginação mybatis
Existe um conceito de plugins (plugins) em Mybatis, que é essencialmente uma ideia interceptadora. A análise específica pode ser encontrada na pesquisa sobre o princípio do Mybatis Interceptor em outro artigo. Nesta base, este artigo exibirá diretamente o código de implementação do projeto real e outras análises relacionadas.
Pagando implementação de código específico
Primeiro, podemos definir a classe abstrata do dialeto para implementar a paginação abstractDialect.java
Classe abstrata public abstrataDialect { / *** Se o limite e o deslocamento são suportados* @return* / public abstract boolean supportmInitoffset (); / ** * Se o limite é suportado * @return */ public abstrato boolean supportLitMit (); / ** * Obtenha SQL após adicionar atributos de paginação * @param sql * @param offset * @param limite * @return */ public abstract string getlimitstring (string sql, int offset, int limite);}Além disso, implementaremos a tecnologia de paginação de página do banco de dados Oracle e MySQL separadamente.
MySqldialect.java-mysql dialeto de paginação
classe pública mysqldialect estende abstrataDialect {public boolean supportslimitoffset () {return true; } public boolean supportslimit () {return true; } public string getlimitString (string sql, int offset, int limite) {if (offset> 0) {return sql + "limite" + deslocamento + "," + limite; } else {return sql + "limite" + limite; }}}Implementação do dialeto oraclect.java-oracle oracledialect.java
classe pública oracledialect estende adialect {@Override public boolean supportLimitoffset () {return false; } @Override public boolean supportLimit () {return false; } @Override public string getlimitString (string sql, int start, int limite) {if (start <0) {start = 0; } if (limite <0) {limite = 10; } Stringbuilder pagesql = new StringBuilder (100); Pagesql.append ("Selecione * de (selecione Temp. retornar pagesql.toString (); }}A implementação do interceptador de plug-in Mybatis correspondente é o seguinte: Intercept DeclarationHandler#Prepare (Connection Con) para criar o método do objeto de instrução SQL
PaginaçãoIntercept.java
@Intercepts ({@Signature (type = DeclarationHandler.class, Method = "Prepare", args = {Connection.class})}) public class Final Class PaginationIntercept implementa interceptor {private final Static Logger Log = LoggerFactory .GetLogger (PaginaçãoInterceptor.class); dialeto privado adialect; public void setDialect (adialect dialeto) {this.dialect = dialect; } @Override Public Object Intercept (Invocation Invocation) lança jogável {// Obtenha diretamente o objeto interceptado, que implementa a classe RoutingStateMementHandler Declaratentler DeclarectionHandler = (DeclarationHandler) Invocation .getTarget (); Boundsql Boundsql = DeclarationHandler.getBoundSql (); // Obtenha metaObject, usado principalmente para obter o objeto e os atributos associados ao DeclarationHandler metaObject MetastatementHandler = metaObject.ForObject (DeclarationHandler, new DefaultObjectFactory (), new DefaLaBjectWrapperFactory ()); MAPPEDSTATEMENT MAPPEDSTMT = (MAPPEDSTATEMENT) METASTATATEMENTHLER. // apenas pagina o método querypagination () if (mapedstmt.getId (). IndexOf ("Querypagination") ==-1) {return Invocation.Proced (); } // Reconstrua o string sql de paginação OriginalSql = (String) MetastatementHandler .getValue ("Delegate.BoundSql.SQL" .Irnn ()); metastatementHandler.setValue ("Delegate.BoundSql.SQL" .Irnn (), 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 ()); retornar invocação.proeced (); } // Objeto de interceptação @Override Public Object Plugin (destino do objeto) {return plugin.wrap (Target, este); } @Override public void setProperties (Propriedades Propriedades) {}}A configuração XML correspondente da mola pode ser a seguinte, tomando a paginação do Oracle como exemplo
<!-Configuração do dialeto Oracle, usado para paginação oracle-> <bean id = "paginationInterceptor"> <nome da propriedade = "dialect"> <bean/> </property> </i bean>
Use o código e a configuração acima para preencher a operação de paginação do banco de dados Oracle e do banco de dados MySQL. E o blogueiro analisa um dos pontos
Mybatis#metaobject-metadata Análise de objetos
Quando o blogueiro usou o código acima, ele ficou intrigado com a classe MetaObject. Ele pode obter diretamente todas as propriedades associadas do objeto que está sendo procurado através do método getValue (). Podemos seguir o código -fonte para aprender mais
MetaObject#forObject()
Todos os objetos de proxy entram através deste método estático
public estático metaObject forObject (objeto objeto, objectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {if (object == null) {return SystemMetaObject.null_meta_object; } else {retorna novo metaObject (object, objectFactory, objectWrapperFactory); }}Podemos observar diretamente o construtor, aqui está o mistério
metaObject privado (objeto objeto, objectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {this.originalObject = object; this.ObjectFactory = ObjectFactory; this.ObjectWrapperFactory = ObjectWrapperFactory; // Todas as aquisições de atributos são obtidas através da classe ObjectWrapper. Aqui, julgamos principalmente o tipo de objeto que é proxyed if (object Instânciaof objectWrapper) {this.objectwrapper = (objectWrapper) objeto; } else if (objectWrapperFactory.haswrapperfor (object)) {this.objectwrapper = objectWrapperFactory.getWrapperFor (this, object); } else if (object instância do map) {this.ObjectWrapper = new MapWrapper (this, (map) objeto); } else if (object instanceOf collection) {this.objectWrapper = new CollectionWrapper (this, (coleção) objeto); } else {// O que costumamos usar é o beanwrapper this.ObjectWrapper = new Beanwrapper (este, objeto); }}Para entender mais infiltrados, continuamos a acompanhar e, finalmente, descobrimos que isso chamará a função construtora da classe refletor
refletor privado (classe <?> clazz) {type = clazz; // Obtenha a classe construtora AddDefaultConstructor (clazz); // Get the get Method define addgetMethods (clazz); // obtenha o método set define addSetMethods (clazz); // Obtenha o conjunto de propriedades internas Addfields (Clazz); readablePropertyNames = getMethods.KeySet (). ToArray (new String [getMethods.KeySet (). size ()]); writeablePropertyNames = setMethods.KeySet (). ToArray (new String [setMethods.KeySet (). size ()]); para (String propName: readablePropertyNames) {caseInsensitivePropertymap.put (propName.Touppercase (Locale.English), propname); } para (String propName: writeablePropertyNames) {caseInsensitivePropertyMap.put (propName.ToupPercase (Locale.English), propName); }} A partir disso, podemos saber que, usando a classe de proxy do refletor e o MetaObject, você pode atravessar todos os atributos associados à classe Proxy. Pegue RoutingStatementHandler como exemplo. Após a operação acima, você pode acessar o delegado de atributo interno e os atributos internos do delegado configuration/objectFactory/typeHandlerRegistry/resultSetHandler/parameterHandler/mappedStatement e outros atributos.
MetaObject#getValue()
O acima explica como procurar as propriedades internas da classe de proxy. Também podemos dar uma breve olhada em como chamá -lo corretamente.
public Object getValue (nome da string) {// PropertyTokenizer é semelhante ao StringTokenizer, exceto que o primeiro é escrito como Delimiter PropertyTokenizer Prop = new PropertyTokenizer (nome); 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); }} A análise específica não será explicada aqui. Como obter a sequência SQL de propriedade do DeclarationHandler pode ser obtida pelo getValue("delegate.boundSql.sql") e os atributos nele devem ser atributos internos (Case Sensitive).
MetaObject#setValue()
O princípio é o mesmo que MetaObject#getValue()
Resumir
O acima exposto é o tutorial sobre o uso do plug-in de paginação mybatis da primavera apresentada pelo editor. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!