Remarque: Ce blog est complètement différent du plug-in actuel de pagination, il est donc recommandé de vérifier le dernier code source et la documentation via l'adresse du projet ci-dessus à comprendre.
J'ai déjà été inquiet pour la requête de pagination MyBatis, et j'ai recherché de nombreux articles connexes en ligne, mais je n'ai pas utilisé le dernier. L'endroit Paged est complètement manuscrit avec SQL et Count SQL, ce qui est très gênant.
Plus tard, pendant un certain temps, je voulais écrire une implémentation de pagination à partir de Mybatis. J'ai écrit une implémentation pour Languagedriver. Il n'y a aucun problème avec la pagination automatique, mais le nombre total de requêtes (comptage) ne peut toujours pas être résolu en même temps, et il n'a pas été résolu.
Récemment, je dois à nouveau utiliser la pagination. Par souci de commodité, je dois écrire une classe de pagination générale, donc je me réfère à nouveau à la plupart des codes de pagination MyBatis sur Internet.
En fait, il y a longtemps, quelqu'un a ouvert l'implémentation de la source sur GitHub, en soutenant MySQL, Oracle et SQLServer, qui est similaire à la référence ci-dessus et a une considération plus complète. Mais je pense que trop de classes sont trop gênantes, j'ai donc mis en œuvre une classe avec un seul intercepteur, qui peut en fait être divisé en deux classes. L'une des classes a été écrite comme une classe statique par moi et placée dans l'intercepteur. Vous pouvez également extraire la classe de page pour faciliter l'utilisation de la page.
Parlons d'abord de la méthode d'implémentation. Ce plugin n'a qu'une seule classe: pagehelper.java
La signature d'intercepteur est:
@Intercepts ({@ Signature (type = instructionHandler.class, method = "prépare", args = {connection.class}), @Signature (type = ResultsEthandler.class, Method = "HandlerSultsSets", args = {Statement.class})})La signature ici est cruciale pour toute la mise en œuvre et l'idée. Tout d'abord, j'intercepte la méthode de préparation pour modifier la pagination SQL et compter la requête. Ensuite, j'intercepte la méthode HandlerreSultSets pour obtenir le dernier résultat de traitement et mettre le résultat dans l'objet page.
Ce qui suit est le code pour modifier la page, qui est une modification des données Oracle. Si vous utilisez d'autres bases de données, vous pouvez modifier le code ici vous-même.
/ ** * Modifiez le SQL d'origine à la pagination SQL * @param sql * @param page * @return * / private String buildPagesql (String sql, page page) {StringBuilder pagesql = new StringBuilder (200); pagesql.append ("select * from (select temp. *, rownum row_id from ("); pagesql.append (sql); pagesql.append (") temp où rownum <=") .append (page.getendRow ()); pagesql.append (") WHERE_ID>") .APPEND (page.getStarTrow (); return pagesql.toString (); } Ensuite, dans la méthode SetPageParameter suivante, une instruction SELECT COUNT doit être modifiée en fonction du type de base de données:
// Nombre total des enregistrements Count CountSql = "SELECT COUNT (0) FROM (" + SQL + ")";Pourquoi ne supporte-je pas diverses bases de données? Je ne pense pas que ce soit nécessaire. Certaines bases de données ne prennent pas en charge la pagination et plus ce plugin est simple, plus il est facile pour les développeurs de comprendre et de modifier. Le modifier dans la requête de pagination dont vous avez besoin n'est certainement pas un problème.
Enfin, le code complet est ajouté (Continuez à lire, il y a aussi la méthode d'utilisation ci-dessous): (cliquez pour télécharger)
Package com.mybatis.util; import org.apache.ibatis.executor.paramètre.ParameterHandler; import org.apache.ibatis.executor.resultSet.ResultSethandler; import org.apache.ibatis.executor.statement.statementHandler; import org.apache.ibatis.mapping.boundsql; import org.apache.ibatis.mapping.maptstatement; import org.apache.ibatis.plugin. *; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.scripting.defaults.defaultParameterHandler; import org.apache.log4j.logger; Importer java.sql. *; Importer java.util.list; import java.util.properties; / ** * Mybatis - Intercepteur de pagination universelle * @author liuzh / abel533 / isea * créé par Liuzh le 14-4-15. * / @Intercepts ({@ Signature (type = statuthandler.class, méthode = "prépare", args = {connection.class}), @Signature (type = ResultsEthandler.class, méthode = "handleresultssets) Logger.getLogger (pageHelper.class); public static final threadLocal <page> localPage = new ThreadLocal <page> (); / ** * Démarrer la pagination * @param pagenum * @param pagesize * / public static void startpage (int pagenum, int pagesize) {localPage.set (new page (pagenum, pageSize)); } / ** * terminer la pagination et renvoyer le résultat. La méthode doit être appelée, sinon LocalPage sera enregistré jusqu'au prochain startpage * @return * / public static Page endPage () {page page = localPage.get (); localPage.remove (); page de retour; } @Override Public Object Intercept (Invocation Invocation) lève Throwsable {if (localPage.get () == null) {return invocation.proceed (); } if (invocation.getTarget () instanceof StatementHandler) {instructionHandler instructionHandler = (statutHandler) invocation.getTarget (); MetaObject MetastatementHandler = SystemMetaObject.ForObject (StatementHandler); // sépare la chaîne d'objets proxy (parce que la classe cible peut être interceptée par plusieurs intercepteurs, plusieurs proxys sont formés, et les deux boucles suivantes // La classe cible la plus primitive peut être séparée) tandis que (MetaStationHandler.HasGetter ("H")) {Object Object = MetastatementHandler.GetValue ("H"); MetaStationHandler = SystemMetaObject.ForObject (Object); } // La classe cible qui sépare le dernier objet proxy while (metaStationHandler.hasgetter ("Target")) {objet objet = metaStationHandler.getValue ("Target"); MetaStationHandler = SystemMetaObject.ForObject (Object); } MaptedStatement mapsstatement = (maptedstatement) metastatementhandler.getValue ("Delegate.maptstatement"); // Informations de page if (localPage.get ()! = Null) {page page = localPage.get (); BOUNDSQL BOURNSQL = (BOURNSQL) MetastatementHandler.getValue ("Delegate.boundsQL"); // Paramètre de page en tant que propriété de ParameterObject ParamètresTring SQL = BOUNDSQL.getsql (); // Réécriture de la chaîne SQL Pagesql = buildPagesql (sql, page); // Réécriture de la pagination SQL MetastatementHandler.SetValue ("Delegate.boundsql.sql", pagesql); Connexion connexion = (connexion) invocation.getArgs () [0]; // Réinitialise le nombre total de pages dans les paramètres de pagination, etc. SetPageParameter (SQL, Connexion, Maptedstatement, BoundsQL, page); // remettez les droits d'exécution sur le prochain retour intercepteur invocation.proceed (); } else if (invocation.getTarget () instanceof ResultsEthandler) {object result = invocation.proceed (); Page Page = LocalPage.get (); PAGE.SETRESULT ((liste) Résultat); Résultat de retour; } return null; } / ** * Intercepter uniquement ces deux types de * instruction Handleler * ResultsEthandler * @param Target * @return * / @Override public Object Plugin (Object Target) {if (cible instance instructionHandler || cible instanceof ResultsEthandler) {return plugin.wrap (cible, this); } else {return Target; }} @Override public void SetProperties (Propriétés Properties) {} / ** * Modifier le SQL d'origine à la pagination SQL * @param sql * @param page * @return * / private String buildPagesql (String sql, page page) {StringBuilder pagesql = new StringBuilder (200); pagesql.append ("select * from (select temp. *, rownum row_id from ("); pagesql.append (sql); pagesql.append (") temp où rownum <=") .append (page.getendRow ()); pagesql.append (") WHERE_ID>") .APPEND (page.getStarTrow (); return pagesql.toString (); } / ** * Obtenez le nombre total d'enregistrements * @param sql * @param connexion * @param mappedstatement * @param boundsql * @param page * / private void SetPageParamètre (String SQL, connexion de connexion, maptedstatement mappedstatement, boundsql boundsql, page) {// nombre total de records de string comptesql = "SELECT COUNT (0)" SQL + ")"; PRÉPAYÉSATATION COUNTSTMT = NULL; ResultSet rs = null; try {countstmt = connection.preparestatement (countSQL); BOUNDSQL COUNTBS = NOUVEAU BOURNSQL (MAPPEDSATATION.GETCONFIGURATION (), COUNTSQL, BOUNDSQL.GetParameTermAppings (), BOUNDSQL.GetParameterObject ()); setParameters (countstmt, maptedstatement, countbs, boundsql.getParameterObject ()); 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 ("ignorer cette exception", e); } enfin {try {Rs.close (); } catch (sqlexception e) {logger.error ("ignorer cette exception", e); } essayez {countstmt.close (); } catch (sqlexception e) {logger.error ("ignorer cette exception", e); }}} / ** * Valeur du paramètre de substitut * @param ps * @param mappedstatement * @param boundsql * @param paramètreObject * @throws sqlexception * / private void SetParameters (préparéstation ps, mappedstatement mappedstatement, paramètre boundsql, objet paramètreRoBject) throws sqEXEXECTION {paramterhandler) DefaultParameterHandler (MaptedStatement, ParameterObject, BoundsQL); ParameterHandler.SetParameters (PS); } / ** * Description: Pagination * Auteur: Liuzh * Mise à jour: Liuzh (2014-04-16 10:56) * / PAGE STATIQUE PUBLIQUE <E> {private int pagenum; Private int pagesize; private int Startrow; private int Endrow; Total long privé; pages int privés; Liste privée <E> Résultat; page publique (int pagenum, int pagesize) {this.pagenum = pagenum; this.pagesize = pagesize; this.startrow = pagenum> 0? (Pagenum - 1) * PageSize: 0; this.endrow = pagenum * pagesize; } public list <e> getResult () {return result; } public void setResult (list <e> result) {this.result = result; } public int getPages () {return pages; } public void setPages (int pages) {this.pages = pages; } public int getEndrow () {return Endrow; } public void setenDrow (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 pagesize) {this.pagesize = pagesize; } public int getStArtrow () {return starTrow; } public void setStartrow (int startrow) {this.startrow = startrow; } public long getTotal () {return total; } public void Settotal (long total) {this.total = total; } @Override public String toString () {return "page {" + "pagenum =" + pagenum + ", pagesize =" + pagesize + ", startrow =" + startrow + ", endrow =" + endrow + ", total =" + total + ", pages =" + pages + '}'; }}} Pour utiliser cet intercepteur, vous devez d'abord configurer l'intercepteur dans la configuration MyBatis:
<flugins> <plugin interceptor = "com.mybatis.util.pagehelper"> </gingin> </glugins>
Lors de la configuration d'un intercepteur, vous devez faire attention à l'emplacement des plugins. L'ordre des plugins est le suivant:
Propriétés ?, Paramètres ?, TYPEALIASES ?, TypeHandlers ?, ObjectFactory?, ObjectWrapperFactory ?, Plugins ?, Environments ?, DatabaseIdProvider ?, MAPTEMERS?
Enfin, il existe l'exemple de code (couche de service) qui appelle cette méthode:
@Override public pagehelper.page <sysloginlog> findSysLogInLog (String Loginip, String Username, String LogIndate, String exitDate, String Logerr, int pageNumber, int pageSize) lance BusinessException {pagehelper.startpage (pAgeNumber, PageSize); sysloginlogmapper.findSysLoginLog (Loginip, nom d'utilisateur, logindate, eXitDate, Logerr); return pagehelper.endpage (); }D'après ce qui précède, nous pouvons voir que l'utilisation de ce plug-in est très simple. Il vous suffit d'utiliser les méthodes de startPage et de page de fin de page de page avant et après la requête. Le résultat de l'appel du code intermédiaire existe déjà dans le résultat de PageHelper. Si vous appelez PageHelper dans un endroit qui renvoie un résultat, le résultat retourné est toujours une liste, et vous pouvez simplement prendre la première valeur (je pense que personne ne l'utilisera comme ça à cet endroit, bien sûr, il n'y a pas d'erreur de cette manière).
De plus, tous les codes MyBatis entre la page de démarrage et la page d'extrémité seront paginés, et PageHelper ne conservera que le dernier résultat. Par conséquent, lorsque vous l'utilisez, vous devez vous assurer qu'une seule requête MyBatis y est exécutée à la fois. S'il y a plusieurs paginations, veuillez utiliser plusieurs fois StartPage et Endpage.
Étant donné que seules les implémentations Oracle sont fournies ici, j'espère que les lecteurs qui se réfèrent à d'autres bases de données implémentées par ce plugin de pagination peuvent également ouvrir le code correspondant.
Adresse du projet: http://xiazai.vevb.com/201612/yuanma/mybatis_pagehelper_jb51.zip
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.