De acordo com a idéia da página a seguir, é fácil implementar o design de vários inquilinos de Mybitas.
Use o interceptador fornecido pela Mybatis. As instruções SQL paginadas são processadas em diferentes SQLs paginos por meio do encapsulamento.
Este exemplo implementou a função de paginação do MySQL e Oracle. Preste atenção ao pacote de cotação a seguir e não o cite incorretamente.
importar java.sql.Connection; importar java.SQL.PreparedStatement; importar java.sql.resultset; importar java.sql.sqLexception; importar java.util.list; importar java.util.properties; org.apache.ibatis.executor.statement.RoutingStatementHandler; importar org.apache.ibatis.executor.statement.statementHandler; importar org.apache.ibatis.mapping.boundsql; import ourg.pache.ibibatis.MagingMatEMent; importação; importapache; importSql; import ourg.pache.ibibatis.Maging.MapTement; importação; org.apache.ibatis.plugin.interceptor; importar org.apache.ibatis.plugin.intercepts; importar org.apache.ibatis.plugin.invocation; importar org.apache.ibatis.plugin.plugin; import org.apache.ibatis.plugin.signature; org.apache.ibatis.scripting.defaults.defaultParameterHandler; importar com.yidao.utils.page; importar com.yidao.utils.reflectHelper;/** * * * Interceptor de paginação, usado para interceptar operações que requerem queda de paginação e depois os pagam. * O princípio da paginação mybatis é implementado usando o Interceptores: * Para usar o JDBC para operar no banco de dados, você deve ter um objeto de instrução correspondente. Antes de Mybatis executar a instrução SQL, ele gerará um objeto de declaração que contém a instrução SQL e a instrução SQL correspondente* é gerada antes da instrução, para que possamos começar com a instrução SQL usada para gerar a instrução antes de gerar a instrução. Na instrução mybatis, a instrução é gerada pelo método * Prepare do objeto RoutingStatementMandler. Portanto, uma das idéias para o uso de um interceptador para implementar a paginação do Mybatis é interceptar o método de preparação da interface Declaração e depois alterar a instrução SQL para a declaração SQL de consulta de paginação correspondente no método interceptor e, em seguida, chama o método de preparação do * DeclarationHandler Object, isto é, chamadas de invocação.ProEced (). * Para a paginação, uma das operações que precisamos fazer no interceptador é contar o número total de registros que atendem às condições atuais. Isso é obtendo a instrução SQL original, alterando -a para a instrução estatística correspondente e substituindo os parâmetros na instrução SQL usando os parâmetros encapsulados do mybatis e os parâmetros de configuração *. Em seguida, a instrução SQL consultando o número de registros é executada para contar o número total de registros. * */ @Intercepts ({ @Signature (type = declarationHandler.class, Method = "Prepare", args = {Connection.class})}) public class PageIntercept implementa interceptor {private String dialect = ""; // DIALECT DIATECT String private String pagesqlid = ""; // ID que precisa ser interceptado no mapper.xml (correspondência regular) interceptação de objetos públicos (invocação de invocação) lança arremesso {// Na verdade, existem apenas duas classes de implementação para o DeclarationHandler, um é o RoutingStatementHandler e o outro é a classe abstrata de classe BaseHandler. // BaseStatementHandler possui três subclasses, nomeadamente SimpleStatementHandler, preparadostatementhandler e callablestatementhandler. // SimpleStatementHandler é usado para processar a instrução, preparar o manipulador de manipulação de manipulação de manipulação preparada e o callablestatementHandler é // processos de callablestatement. Mybatis cria um RoutingStatementHandler ao processar instruções SQL. No RoutingStatementHandler, existe uma propriedade delegada do tipo // do tipo DeclarationHandler. O RoutingStatementHandler criará um BaseStatementHandler correspondente de acordo com as diferentes declarações, ou seja, SimpleStatementHandler, // preparou o MandalHandler ou o callablestatementHandler. No RoutingStatementHandler, todos os métodos de interface DeclarationHandler são implementados pelo delegado correspondente ao delegado chamado. // Marcamos o interceptador apenas intercepta o método de preparação da interface DeclarationHandler com @Signature na classe PageInterceptor. Como o Mybatis apenas o envolve através do método do plug -in interceptador ao estabelecer o RoutingStatementHandler, o objeto de destino que intercepte aqui deve ser o objeto RoutingStatementHandler. if (Invocation.getTarget () Instância de RoutingStatementHandler) {RoutingStatementHandler DeclarationHandler = (RoutingStatementHandler) Invocation.getTarget (); DeclarationHandler delegate = (DeclarationHandler) reflecThelper.GetFieldValue (DeclarationHandler, "Delegate"); Boundsql Boundsql = Delegate.getBoundSql (); Objeto obj = boundSql.getParameTerObject (); if (obj instanceof página <?>) {página <?> página = (página <?>) obj; // Recuperar a propriedade MappEdStatement do BaseStatementHandler da classe dos pais delegados mapedstatement mapedstatement = (MappedStatement) reflecThelper.getfieldValue (delegado, "mapedstatement"); // O parâmetro do método de preparação interceptado é uma conexão de conexão de conexão conexão = (conexão) invocação.getargs () [0]; // Obtenha a instrução SQL atualmente executada, ou seja, a instrução SQL que escrevemos diretamente na declaração de mapeamento do mapeador string sql = boundsql.getSql (); // Defina o número total de registros para o objeto de parâmetro atual da página this.setTotalRecord (página, MappEdStatement, conexão); // Obtenha a instrução SQL PAGAGE PAGESQL = this.getPagesql (página, SQL); // Use a reflexão para definir o atributo SQL correspondente ao BoundSQL atual para criar uma boa instrução SQL pagin para nós reflecThelper.SetFieldValue (Boundsql, "SQL", PAGESQL); }} return invocation.proeced (); } /*** Defina o número total de registros para a página atual do objeto do parâmetro** @param página de mapeamento de mapeamento* @param mapedstatement mapeando instrução de mapeamento* @param conexão de banco de dados atual conexão* /private void SettalRecord (página <? Esse BoundsQL é realmente o mesmo objeto que o BoundsQL que obtivemos usando o DeclarationHandler. // O BoundSQL no Delegate também é obtido através do método MappEdStatement.GetBoundSQL (Paramobj). Boundsql Boundsql = MappEdStatement.GetBoundSql (Page); // Obtenha a instrução SQL correspondente String sql = Boundsql.getSql (); // Obtenha a instrução SQL correspondente que calcula o número total de registros, consultando a instrução SQL Countsql = this.getCountSql (SQL); // Obtenha o mapa de parâmetros correspondente através da lista Boundsql <MeameTerMapping> parameTerMAppings = boundSql.getParameTerMAppings (); // Use a configuração, a instrução SQL contagens QL para consultar registros, mapeamento de parâmetros ParameterMAppings e página de objeto de parâmetro para criar um objeto Boundsql correspondente a registros de consulta. Boundsql countBoundSql = new Boundsql (MappEdStatement.getConfiguration (), CountSQL, ParameTerMAppings, Page); // Crie um objeto ParameterHandler para definir parâmetros por meio do MappEdStatement, Página do objeto do parâmetro e BoundsQL Object CountBoundSql. ParameterHandler ParameterHandler = new DefaultParameterHandler (MappedStatement, Page, CountBoundSQL); // Crie um objeto preparado de estatamento correspondente correspondente ao countSQL por meio da conexão. Preparado PSTMT de estatuto preparado = null; ResultSet rs = null; tente {pstmt = Connection.Preparestatement (contagemSQL); // Definir parâmetros parâmetros parameterHandler para o objeto preparado de estatamento através do parameterHandler.setParameters (PSTMT); // Em seguida, ele é executado para obter o número total de registros e obter os resultados. rs = pstmt.executeQuery (); if (rs.Next ()) {int totalRecord = rs.getInt (1); // Defina o número total de registros para o parâmetro atual Object.SetTotalRecord (TotalRecord); }} catch (sqLexception e) {e.printStackTrace (); } finalmente {tente {if (rs! = null) rs.close (); if (pstmt! = null) pstmt.close (); } catch (sqLexception e) {e.printStackTrace (); }}} / * * return "Select count (*)" + sql.substring (índice); } /*** Obtenha a instrução SQL de consulta de paginação correspondente com base no objeto da página. Apenas dois tipos de banco de dados são fabricados aqui, MySQL e Oracle * Nenhum outro banco de dados é Paging * * @param Page Paging Object * @param SQL Declaração SQL original * @return */ private string getPagesql (página <? if ("mysql" .equalsignorecase (dialeto)) {return getmysqlpagesql (página, sqlbuffer); } else if ("oracle" .equalsignorecase (dialeto)) {return getoraclepagesql (página, sqlbuffer); } return sqlbuffer.toString (); } / *** Obtenha a instrução de consulta paginada para o objeto MySQL Database* @Param Page Paging* @param sqlbuffer stringbuffer objeto que contém a instrução SQL original* @return mysql database Pagfer declaração* / private string getMysqlpagesql (página <? A posição do registro no MySQL começa em 0. // System.out.println ("página:"+página.getPage ()+"--------"+página.getRows ()); int offset = (página.getPage () - 1) * página.getRows (); SQLBUFFER.APNEND ("LIMIT") .APNEND (OFFSET) .APNEND (","). Append (Page.getRows ()); return sqlbuffer.toString (); } / *** Obtenha a declaração de consulta paginada para o Oracle Database* @param Page Paging Object* @param objeto sqlbuffer stringbuffer que contém a instrução SQL original* @Return Pagination Consulta Declaração para Oracle Database* / Priver String GetoraclePagesQL (página <? A paginação do Oracle é realizada através do ROOWNUM e o ROWNUM começa em 1 Int Offset = (Page.getPage () - 1) * Page.getRows () + 1; sqlbuffer.insert (0, "Selecione u.*, ROWNUM R de (") .APNEND (") u wHERE ROWNUM <") .APNEND (Offset + Page.getRows ()); sqlbuffer.insert (0, "Selecione * de (") .append (") onde r> =") .append (offset); // A instrução SQL acima se parece com o seguinte: // SELECT * de (selecione u. *, ROWNUM R de (selecione * de t_user) u onde rownum <31) onde r> = 16 retorna sqlbuffer.tostring (); } / *** Método para encapsular o objeto original correspondente ao plugin interceptor* / público do objeto (objeto arg0) {// ToDO Method Stub if (arg0 instanceOf DeclarationHandler) {return plugin.wrap (arg0, this); } else {return arg0; }} / *** Defina as propriedades definidas ao registrar o interceptor* / public void setProperties (Propriedades P) {} public string getDialect () {return dialeect; } public void SetDialect (String Dialect) {this.dialect = dialect; } public string getPagesqlid () {return pagesqlid; } public void setPagesqlid (string Pagesqlid) {this.pagesqlid = Pagesqlid; }} Configuração XML:
<!-Configuração de programação da interface mybatis-> <Bean> <!-BasePackage especifica o pacote a ser digitalizado. Os mapeadores deste pacote serão pesquisados. Múltiplos pacotes podem ser especificados, separados por vírgulas ou semicolons-> <propriedade name = "Basepackage" value = "com.yidao.mybatis.dao" /> <nome da propriedade = "sqlsessionFactoryBeanName" value = "sqlSessionFactory" /> < /bEan> <!-mybatis " name = "dialect" value = "mysql"/> <!-intercepte a instrução com id contendo caracteres de consulta no arquivo mapper.xml-> <propriedade name = "Pagesqlid" value = ".*Query $"/> </ean>
Classe de página
pacote com.yidao.utils;/** Olhe você mesmo, quais campos são necessários para adicionar a ele*/public classe {private inteiro linhas; página inteira privada = 1; Inteiro privado TotalRecord; public integer getRows () {retorna linhas; } public void setrows (linhas inteiras) {this.rows = linhas; } public integer getPage () {retorna página; } public void setPage (página inteira) {this.page = Page; } public integer getTotalRecord () {return totalRecord; } public void SettotalRecord (Integer TotalRecord) {this.TotalRecord = TotalRecord; }} Classe reflectHelper
pacote com.yidao.utils; importar java.lang.reflect.field; importar org.apache.commons.lang3.reflect.fieldutils; public class reflecThelper {public static objeto getfieldValue (objeto obj, string fieldname) {if (obj == null) {return null; } Field TargetField = getTargetfield (obj.getclass (), fieldname); tente {return fieldUtils.readfield (Targetfield, obj, true); } catch (ilegalAccessException e) {E.PrintStackTrace (); } retornar nulo; } Campo estático público GetTargetField (classe <?> TargetClass, String FieldName) {campo de campo = null; tente {if (TargetClass == NULL) {Return Field; } if (object.class.equals (TargetClass)) {Return Field; } field = fieldUtils.getDecLaredField (TargetClass, FieldName, True); if (field == null) {field = getTargetfield (TargetClass.getSuperclass (), FieldName); }} Catch (Exceção e) {} Return Field; } public static void setFieldValue (object obj, string fieldname, valor do objeto) {if (null == obj) {return;} campo de campo de campo = gettargetfield (obj.getclass (), fieldname); tente {fieldutils.writefield (Targetfield, obj, valor); } catch (ilegalAccessException e) {E.PrintStackTrace (); }}}O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.