Verstehen Sie vor dem Teilen des Ausführungscode für die gesamte Abfrageseite zuerst den Ausführungsprozess.
1. Im Allgemeinen verwendet es MyBatis-Plug-In-Interceptor vor der SQL-Ausführung und füge der Abfrageanweisung Limit XX hinzu
2. Verwenden Sie ein Seitenobjekt, um den gesamten Ausführungsprozess durchzuführen. Dieses Seitenobjekt erfordert das Schreiben von Front-End-Paginationskomponenten in Java.
3.. Verwenden Sie einen relativ vollständigen Satz von dreischichtigen Einrichtungen, DAO und Service, um diese Paginierungsarchitektur zu unterstützen
4. Einige Hilfsklassen, die auf dieser Seite verwendet werden
Hinweis: Es werden viele Inhalte geteilt. Ich werde die erforderlichen Gläser nacheinander nicht auflisten. Wenn Sie diese Paginierungsfunktion verwenden, suchen Sie nachts nur nach JAR -Paketen. Verwenden Sie das Maven -Paket, um so weit wie möglich zu importieren, da Maven Versionskonflikte und andere Vorteile reduzieren kann.
Ich kann nur sagen, dass Sie diese einfachere Paging -Funktion so schnell wie möglich verwenden können. Wenn Sie es nicht verstehen, fügen Sie mich bitte zu QQ hinzu und besprechen Sie es gemeinsam. Schwöre nicht! Auch der Artikel mag relativ groß sein, aber es wird sich etwas Zeit nehmen, ihn lesen und üben, er wird auf jeden Fall viel gewinnen.
Schritt 1: Da sich das Thema darum dreht, wie man paginiert, beginnen wir mit MyBatis. Erstens werden wir zwei weitere wichtige Konfigurationsdateien, die sich auf MyBatis beziehen, für ein kurzes Verständnis herausnehmen. Einer ist mybatis-config.xml und der andere ist die Mapper-Konfigurationsdatei, die der Entität entspricht. Ich werde Kommentare zur Konfigurationsdatei schreiben, und jeder wird sie auf einen Blick verstehen.
mybatis-config.xml
<! DocType configuration public "-// mybatis.org//dtd config 3.0 // ede -> <Einstellung Name = "CacheEnabled" value = "false"/> <!-Aktivieren oder deaktivieren Sie das faule Laden global. Bei deaktivierter Deaktivierung werden alle zugeordneten Objekte sofort geladen. -> <Einstellung name = "LazyLoadingInabled" value = "true"/> <!-Wenn ein Objekt mit einer faulen Ladeeigenschaft eine Eigenschaft lädt, wenn sie aufgerufen wird. Andernfalls wird jede Eigenschaft nach Bedarf geladen. -> <Einstellung name = "AggresivInAnyLoading" value = "true"/> <!-ob ein einzelner SQL zulässt, mehrere Datensätze zurückzugeben (abhängig von der Kompatibilität des Treibers) Standard: true-> <Einstellungsname = "MultipleresulatsetSenable" Value = "True"/> <! name = "usecolumnLabel" value = "true"/> <!- Ermöglichen Sie JDBC, Primärschlüssel zu generieren. Der Antriebsunterstützung ist erforderlich. Wenn diese Einstellung auf True gesetzt wird, erzwingt diese Einstellung den generierten Primärschlüssel, einige Laufwerke sind inkompatibel, können jedoch weiterhin ausgeführt werden. Standard: Falsch-> <Einstellung Name = "useGeneratedKeys" value = "false"/> <!-Geben Sie an, wie mybatis automatisch Spalten der Datenbanktabelle kartiert: Nicht verbergen: Teil voll: Alle-Einstellungsname = "AutomappingBehavior" value = "partiell"/> <! Wiederholen Sie Anweisungen und Batch-Updates)-> <Einstellung Name = "DefaultExecUtortype" Value = "Simple"/> <!-Felder mit Camel-Nomenklatur konvertieren. -> <Einstellung name = "MAPUNDERSCORETOCAMELCASE" value = "true"/> <!-Setzen lokaler Cache-Reichweite Sitzung: Es gibt Datenfreigabe-Anweisung: Anweisung Scope (dies ist keine Datenfreigabe) Defalut: Sitzung-> <Seting Name = "Localcachescope" Value = "Session"/> <! Geben Sie beim Einfügen eines Nullwerts ein-> <Einstellung name = "jdbctypeFornull" value = "null"/> <Einstellungsname = "logprefix" value = "dao. alias = "user"> </typealias> <typealias type = "com.store.base.secondmodel Page Interceptor für MyBatis konfiguriert, und wir müssen diesen Seite Interceptor selbst implementieren -> <Plugins> <Plugin interceptor = "com.store.base.secondModel.base.pageInterceptor.PaginationInterceptor"/> </plugins> </configuration>
Ein ProductMapper.xml wird als Testobjekt verwendet, und diese Mapper -Datei konfiguriert einfach eine Abfrageanweisung, die verwendet werden muss.
<? namespace = "com.store.base.secondModel.pratice.dao.productdao"> <sql id = "Basecolumns"> id, product_name as productName, product_no als productno, Preis als Preis </sql> <select id = "fandlist" resultType = "com.store.base.secondModel.pratice.model.Product"> Select <include refid = "Basecolumns"/> von t_store_product </select> </mapper>
Schritt 2: Als nächst
(1) BaseInterceptor Interceptor Basic Class
(2) Paginationsinterceptor Die Pagination Plugin -Klasse, die wir verwenden möchten, erben Sie die obige Basisklasse
.
(4) Dialekt, MySQLDIalect
Im Folgenden sind die Freigabesanzeigen dieser Kategorien aufgeführt
BaseInterceptor.java
paket com.store.base.secondmodel.base.pageInterceptor; importieren java.io.serializable; Import Java.util.Properties; import org.apache.ibatis.logging.log; import org.apache.ibatis.logging.logfactory; import org.apache.ibatis.plugin.Interceptor; import com.store.base.secondmodel.base.global; import com.store.base.secondmodel.base.page; import com.store.base.secondmodel.base.dialect.dialect; import com.store.base.secondmodel.base.dialect.mysqldialect; com.store.base.util.reflections; / ** * MyBatis Pagination Interceptor Basisklasse * @Author yiyong_wu * */ public abstract Class BaseInterceptor implementiert Interceptor, serialisierbar {private statische endgültige long serialversionuid = 1l; Protected Static Final String page = "Seite"; geschützte statische endgültige String -String -Delegate = "Delegate"; geschützte statische endgültige Zeichenfolge maped_statement = "MapPedStatement"; protected log log = logFactory.getLog (this.getClass ()); geschützter Dialekt -Dialekt; / *** Parameter konvertieren und überprüfen. {return (Seite <Object>) parameterObject; } else {return (Seite <Object>) reflections.getFieldValue (parameterObject, Seite); }} catch (Ausnahme e) {return null; }} /*** Setzen Sie Eigenschaften, unterstützen Sie benutzerdefinierte Dialektklassen und So formulieren Sie Datenbanken* <Code> Dialektklasse < /code>, benutzerdefinierte Dialektklassen. Dies kann ohne Konfigurieren von * <ode> dbms </ode> Datenbanktyp, Datenbank, unterstützt durch das Plug-In * <Code> SQLpattern </code> SQL-ID, die abgefangen werden müssen * @param p-Eigenschaften */Protected Void InitProperties (Eigenschaften p) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) P) -Properien (Eigenschaften p) (Dialekt-Dialekt = null; null; String dbType = global.getConfig ("jdbc.type"); if ("mysql" .Equals (dBType)) {Dialect = new mySqldialect (); } if (dalect == null) {neue RunTimeException werfen ("MyBatis Dialect -Fehler."); } Dialekt = Dialekt; }}Paginationsinterceptor.java
paket com.store.base.secondmodel.base.pageInterceptor; Import Java.util.Properties; import org.apache.ibatis.executor.executor; import org.apache.ibatis.mapping.boundSql; import org.apache.ibatis.mapping.mappingStatement; import org.apache.ibatis.mapping.sqlSource; import org.apache.ibatis.plugin.intercepts; import org.apache.ibatis.plugin.invocation; import org.apache.ibatis.plugin; import org.apache.ibatis.plugin.signature; import org.apache.ibatis.reflection.metaObject; import org.apache.ibatis.session.resaulthandler; import org.apache.ibatis.session.rowbounds; import com.store.base.secondmodel.base.page; import com.store.base.secondmodel.base.util.stringutils; com.store.base.util.reflections; /*** Datenbank Paging -Plugin, nur Abfragenanweisungen. * @Author yiyong_wu * */ @Intercepts ({@signature (type = executor.class, method = "query", args = {mappedStatement.class, Object.class, RowBounds.class, ResultHandler. @Override Public Object Intercept (Invocation Invocation) löscht Throwable {Final MapChdStatement MapChdStatement = (MapChedStatement) Invocation.getargs () [0]; Objektparameter = Invocation.getargs () [1]; BoundSQL boundSQL = MADPDStatement.getBoundSQL (Parameter); Object ParameterObject = bodernsql.getParameterObject (); // Die Paginationsparameter -Objektseite <Objekt> page = null abrufen; if (parameterObject! = null) {page = convertParameter (parameterObject, page); } // Wenn das Paging -Objekt festgelegt ist, wird das Paging durchgeführt, wenn (Seite! = Null && page.getPageSize ()! } String Originalsql = bodenSQL.getSQL (). TRIM (); // Die Gesamtzahl der Datensätze abrufen. // Pagination -Abfrage lokalisierte Objekte zum Ändern der Datenbank und zur Änderung der Implementierungsstring -Seitensql = SQLHELPER.GeneratePagesql (OriginalsQL, Seite, Dialekt); invocation.getargs () [2] = new rowBounds (rowBounds.no_row_offset, rowBounds.no_row_limit); BoundSQL NewBoundSQL = new boundSQL (mappedStatement.getConfiguration (), pagesql, boundsql.getParametermappings (), boundSQL.getParameterObject ()); // MyBatis -Pagination foreach Parameter Fehler starten if (Reflections.GetfieldValue (bodernsql, "metaparameters")! Reflections.SetfieldValue (NewBoundSQL, "Metaparameters", MO); } // MyBatis -Pagination foreach Parameterausfall lösen. invocation.getArgs () [0] = newms; } return Invocation.Procece (); } @Override öffentliches Objekt -Plugin (Objektziel) {return plugin.wrap (target, this); } @Override public void setProperties (Eigenschaften Eigenschaften) {Super.initProperties (Eigenschaften); } private mapPedStatement CopyFromPappedStatement (MADPDStatement MS, SQLSource NewsqlSource) {MapPortedStatement.builder Builder = new MadPedStatement.builder (ms.getConfiguration (), ms.getId (), Newsqlsource, ms.getsqlcommandtype (); Builder.Resource (mssgetResource ()); Builder.fetchsize (mssGetfetchsize ()); builder.Statementtype (ms.getStatementtype ()); Builder.KeyGenerator (FrauGetKeyGenerator ()); if (mssgeKeyProperties ()! }} builder.timeout (mssgetTimeout ()); Builder.Parametermap (FrauGetParametermap ()); Builder.ResultMaps (FrauGetResultMaps ()); Builder.cache (mssgetCache ()); return Builder.build (); } public static class boundSQLSQLSource implementiert sqlSource {boundSQL bodernsql; public bandsqlsqlSource (bodernSQL bodernsql) {this.boundSQL = bodernSQL; } @Override public bandsql getBoundSQL (ObjektparameterObject) {return bodersql; }}}Sqlhelper.java
paket com.store.base.secondmodel.base.pageInterceptor; Import Java.sql.Connection; importieren java.sql.preeParedStatement; importieren java.sql.resultset; importieren java.sql.sqlexception; importieren java.util.list; Import Java.util.Regx.Matcher; Import Java.util.Regex.Pattern; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.executor.executorexception; import org.apache.ibatis.logging.log; import org.apache.ibatis.mapping.boundSql; import org.apache.ibatis.mapping.mappingStatement; import org.apache.ibatis.mapping.parametermaping; import org.apache.ibatis.mapping.parametermode; import org.apache.ibatis.reflection.metaObject; import org.apache.ibatis.reflection.property.propertytokenizer; import org.apache.ibatis.scripting.xmltags.foreachsqlnode; import org.apache.ibatis.session.configuration; import org.apache.ibatis.type.typeHandler; import org.apache.ibatis.type.typeHandlerregistry; import com.store.base.secondmodel.base.global; import com.store.base.secondmodel.base.page; import com.store.base.secondmodel.base.dialect.dialect; import com.store.base.secondmodel.base.util.stringutils; com.store.base.util.reflections; /*** SQL Tool Class* @Author yiyong_wu** /public class sqlhelper { /*** Standard privater Konstruktor* /private sqlhelper () {} /*** Setzen Sie den Wert für SQL -Parameter (?), Org. SQL Das Objekt der Anweisung. * @param mappedStatement MappedStatement * @param boundSql SQL * @param parameterObject ParameterObject ParameterObject @throws java.sql.SQLException Database exception*/ @SuppressWarnings("unchecked") public static void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object ParameterObject) löst SQLEXception {errorContext.instance (). Aktivität ("Einstellparameter"). Liste <PARAMETERMAPPING> ParameterMappings = bodernSQL.getParametermappings (); if (parameterMappings! = null) {configuration configuration = mappedStatement.getConfiguration (); TypeHandlerregistry typeHandlerregistry = configuration.gettypeHandlerregistry (); MetaObject metaObject = parameterObject == null? null: configuration.newmetaObject (parameterObject); für (int i = 0; i <parameterMappings.size (); i ++) {parameterMapping parametermaping = parameterMappings.get (i); if (parametermaping.getMode ()! = parametermode.out) {Objektwert; String PropertyName = parametermaping.getProperty (); PropertyTokenizer prop = new PropertyTokenizer (PropertyName); if (parameterObject == null) {value = null; } else if (typeHandlerregistry.hastypeHandler (parameterObject.getClass ()) {value = parameterObject; } else if (boundsql.hasadDitionalParameter (PropertyName)) {value = bandsql.getAdDitionalParameter (PropertyName); } else if (PropertyName.Startswith (foreachSQlnode.item_prefix) && boundsql.hasadditionalParameter (prop.getName ())) {value = boundsql.getAditionalParameter (prop.getName ()); if (value! }} else {value = metaObject == null? NULL: metaObject.getValue (Eigentumsname); } @SuppressWarnings ("rawtypes") typeHandler typeHandler = parametermaping.gettTypeHandler (); if (typeHandler == null) {throw New executorexception ("Es wurde kein TypeHandler für den Parameter gefunden" + PropertyName + "der Anweisung" + mappedStatement.getId ()); } typeHandler.setParameter (ps, i + 1, Wert, parametermaping.getJdbcType ()); }}}} / *** Abfrage Gesamtdatensätze* @param SQL SQL Anweisung* @param Connection Database Connection* @Param MadPedStatement MADKAPT* @PARAM ParameterObject Parameter* @param boundSQL boundSQL* @return Gesamtzahl der Datensätze* @Throws SQLECTELS SQL SQL SQL MODSPRODEL ERRAGE* / PUBLIC STATIC STATIC INT STATIC INT GETCOTCOUNT (ENGLEINE SQLECTEL SQL SQL SQL ERGEBNISSE* / PUBLIC STATIC STATION STATION STATICE Int. kartierstatement, endgültiges Objekt parameterObject, endgültig bodeSQL bodernSQL, log log) löscht sqlexception {string dbname = global.getConfig ("jdbc.type"); endgültige String countSQL; if ("oracle" .equals (dbname)) {countSql = "Wählen Sie count (1) aus (" + sql + ") tmp_count"; } else {countSQL = "Wählen Sie count (1) aus (" + REMEDORTERS (SQL) + ") TMP_COUNT"; } Verbindung conn = Verbindung; PrepedStatement ps = null; ResultSet rs = null; try {if (log.isdebugenabled ()) {log.debug ("zählen } if (conn == null) {conn = mappedStatement.getConfiguration (). Getenvironment (). getDataSource (). getConnection (); } ps = conn.preparestatement (countSQL); BoundSQL countbs = new boundSQL (MapChdStatement.getConfiguration (), countSQL, boundSQL.getParameterMappings (), ParameterObject); // MyBatis -Pagination foreach Parameter Fehler starten if (Reflections.GetfieldValue (bodernsql, "metaparameters")! Reflections.SetfieldValue (Countbs, "Metaparameter", MO); } // MyBatis -Pagination foreach -Parameterausfallende Ende sqlhelper.setParameters (PS, MapChdStatement, Countbs, ParameterObject); rs = ps.executeQuery (); int count = 0; if (rs.Next ()) {count = rs.getint (1); } return count; } endlich {if (rs! = null) {rs.close (); } if (ps! = null) {ps.close (); } if (conn! = null) {conn.close (); }}} / *** Generieren Sie spezifische Seiten gemäß Datenbank -Dialekt* @param SQL SQL -Anweisung in @param SQL Mapper* @param Page Paging -Objekt* @param -Dialekt -Dialekttyp* @return Paging SQL* / public static String generatepagesql (String SQL, Page <Objekt> Seite) {Dialekt) {ifsupports (SQL, Page {Objekt> page) {if) {if (Dialekt.Supports (SQLIMit dialect.getLimitString (SQL, page.getfirstresult (), page.getMaxResults ()); } else {return SQL; }} /*** Entfernen Sie die Auswahlklausel von Qlstring. * @param hql * @return */ @Suppresswarnings ("unbenutzt") private statische Zeichenfolge entfernt (String Qlstring) {int beginpos = qlstring.tolowerCase (). Indexof ("from"); return qlstring.substring (beginpos); } /*** Entfernen Sie die OrderBy -Klausel von HQL. *@param hql *@return */private statische String REMEDORTERS (String QlString) {muster p = muster.comPile ("order // s *von [// w | // w | // s | // s] *", muster.case_inemsitiv); Matcher M = P.Matcher (Qlstring); StringBuffer sb = new StringBuffer (); while (m.find ()) {M.Appendreplacement (SB, ""); } M.AppendTail (SB); return sb.tostring (); }}Dialect.java -Schnittstelle
Paket com.store.base.secondmodel.base.dialect; / *** Ähnlich wie Hibernate, aber nur der Paging -Teil ist vereinfacht* @author yiyong_wu**/ public interface Dialekt {/ *** unterstützt die Datenbank selbst die aktuelle Paging -Abfragemethode für das Paging* Wenn die Datenbank nicht unterstützt wird, wird die Datenbank nicht unterstützt. / ** * SQL in Pagination SQL konvertieren und Paging SQL separat aufrufen }Mysqldialect.java
Paket com.store.base.secondmodel.base.dialect; / ** * Implementierung des MySQL -Dialekts * @Author yiyong_wu * */ public class mySqldialect implementiert den Dialekt {@Override public boolean supportLimit () {return true; } @Override public String getLimitString (String SQL, int offset, int limit) {return getLimitString (SQL, Offset, Integer.toString (Offset), Integer.toString (Limit)); } /*** Verwandeln Sie SQL in eine PAGED SQL -Anweisung, wodurch der Offset und die Grenzen durch Platzhalter ersetzt werden. * <pre> * Zum Beispiel mySQL * Dialekt.getLimitString ("aus dem Benutzer auswählen", 12, ": Offset", 0, ": limit") wird * ausgewählt * aus Benutzerlimit: Offset,: Limit * </pre> * * @param SQL Tatsächliche SQL -Anweisung * @Param OffsetPlace -Pagination Pagination Pagination Pagination Pagination. Platzhalter @Return Pagination SQL, der Platzhalter enthält */ public String getLimitString (String SQL, int Offset, String OffsetPlacePlace, String LimitPlaPlader) {StringBuilder StringBuilder = new StringBuilder (SQL); StringBuilder.Append ("Limit"); if (offset> 0) {StringBuilder.Append (OffsetPlaceHolder) .Append (","). Append (limitPlaPleholder); } else {stringBuilder.Append (limitPlacePlader); } return StringBuilder.toString (); }}Fast hier haben wir geteilt, wie man die gesamte Seite implementiert, aber wir haben wichtigere Aufgaben. Wenn wir wollen, dass das Ganze läuft, müssen wir grundlegende Arbeiten haben. Als nächstes analysieren wir den gesamten Satz von Seitenobjekten und die dreischichtige Architektur, auf der sie basiert, und verwenden Produkte als Entität für die Analyse. Nachdem die Belohnungen über eine komplette dreischichtige Architektur gesprochen haben, werden sie auf jeden Fall voll sein. Lassen Sie uns in der Reihenfolge des Unternehmens des Unternehmens darüber sprechen.
Erstens müssen wir zwei abstrakte Entitätsklassen BasisEntity und DataEntity für unsere Entitäten erben.
BaseEntity.java platziert hauptsächlich die Seitenmitgliedvariable. Nach dem Erben kann jede Entität diese Mitgliedsvariable haben.
Paket com.store.base.secondModel.base; importieren java.io.serializable; import Java.util.map; importieren javax.xml.bind.annotation.xmltransient; import org.apache.commons.lang3.stringutils; import org.apache.commons.lang3.builder.reflectionToStringBuilder; import com.fasterxml.jackson.annotation.jsonignore; import com.google.common.collect.maps; import com.store.base.model.storuser; / ** * Die Top-Level-Entität * @Author yiyong_wu * * @param <t> */ public abstract Class BaseEntity <T> Implementiert serialisierbare {private statische endgültige long serialversionuid = 1l; / ** * Löschen Sie das Tag (0: Normal; 1: löschen; 2: prüfung;) */ public static Final String del_flag_normal = "0"; public static Final String del_flag_delete = "1"; public static Final String del_flag_audit = "2"; / *** Entitätsnummer (eindeutige Kennung)*/ Protected String ID; / *** aktueller Benutzer*/ Protected StoreUser Currentuser; / *** aktuelles Entitätspaginierungsobjekt*/ geschützte Seite <T> Seite; / ** * benutzerdefinierte SQL (SQL Identifier, SQL -Inhalt) */ private map <string, string> sqlmap; public baseEntity () {} public baseEntity (String id) {this (); this.id = id; } public String getId () {return id; } public void setID (String -ID) {this.id = id; } / *** Dies wird aufgerufen, wenn Sie Updates für Shiro durchführen, um den aktuellen Benutzer zu erhalten } return currentuseer; } public void setCurrentuser (stoteruser currentUser) {this.currentUser = currentUser; } @Jsonignore @xmltransient public page <t> getPage () {if (page == null) {page = new Page <> (); } Rückgabeseite; } public Page <T> setPage (Seite <T> Seite) {this.page = Seite; Rückgabeseite; } @Jsonignore @xmltransient public map <string, string> gotsQlmap () {if (sqlmap == null) {sqlmap = maps.newhashMap (); } return SQLMAP; } public void setSQLMAP (MAP <String, String> SQLMAP) {this.sqlmap = sqlmap; } / ** * Führen Sie die Methode vor Insertion aus, Unterklasse implementiert * / öffentliches abstraktes void preinsert (); / ** * Führen Sie die Methode vor dem Update aus, Unterklasse implementiert */ öffentliches abstraktes void preupdate (); /*** Ob es sich um einen neuen Datensatz (Standard: Falsch) handelt, rufen Sie setisNewRecord () ein, um einen neuen Datensatz festzulegen und eine benutzerdefinierte ID zu verwenden. * Nach der Einstellung auf True ist die Anweisung Insert zum Ausführen gezwungen. Die ID wird nicht automatisch generiert und muss manuell übergeben werden. * @return */ public boolean getisnewRecord () {return stringutils.isblank (getId ()); } / *** globales variables Objekt* / @jsonignore public global getgloBal () {return global.getInstance (); } / *** Datenbankname erhalten* / @jsonignore public String getDbName () {return global.getConfig ("jdbc.type"); } @Override public String toString () {return ReflectionToStringBuilder.toString (this); }}DataEntity.java, speichert hauptsächlich Aktualisierungszeiten und Löschen, erstellen Benutzer, den Benutzer, das logische Löschungsflag usw. aktualisieren, usw.
Paket com.store.base.secondModel.base; import Java.util.date; import org.hibernate.validator.constraints.length; import com.fasterxml.jackson.annotation.jsonFormat; import com.fasterxml.jackson.annotation.jsonignore; import com.store.base.model.storuser; / ** * Data Entity * @Author yiyong_wu * * @param <t> */ public abstract Class DataEntity <T> erweitert BaseEntity <T> {private statische endgültige long serialversionuid = 1l; geschützter StoreUser CreateBy; // Creator Protected Date erstellte Erstellung; // Erstellungsdatum geschütztes StoreUser Updateby; // Updater Protected Datum aktualisiert; // Aktualisiertes Datum Protected String Delflag; // Delete tag (0: normal; 1: delete; 2: pdit) public datentity () {super (); this.delflag = del_flag_normal; } public DataEntity (String -ID) {super (id); } / ** * Führen Sie die Methode vor dem Insertion aus. // if (stringutils.isnotblank (user.getId ())) {// this.updateby = user; // this.createby = user; //} this.updatedate = new Date (); this.createdate = this.updatedate; } / ** * Führen Sie die Methode vor dem Update aus. // if (stringutils.isnotblank (user.getId ())) {// this.updateby = user; //} this.updatedate = new Date (); } // @jsonignore Public StoreUser getCreateby () {return createBy; } public void setCreateby (storingUser createBy) {this.createby = createBy; } @JsonFormat (muster = "yyyy-mm-dd hh: mm: ss") public date getCreatedate () {return createdate; } public void setCreatedate (Datum erstellt) {this.createdate = createdate; } // @jsonignore Public StoreUser getupdateBy () {return updateBy; } public void setupdateby (storingUser updateby) {this.updateby = updateBy; } @JsonFormat (muster = "yyyy-mm-dd hh: mm: ss") public date getupdatedate () {return aktualisiert; } public void setupdatedate (Datum aktualisiert) {this.updatedate = updatatatat; } @Jsonignore @Length (min = 1, max = 1) public String getDelflag () {return Delflag; } public void setDelflag (String delflag) {this.delflag = Delflag; }}Produkt.java Produktkategorie
Paket com.store.base.secondModel.PRATICE.MODEL; import com.store.base.secondmodel.base.dataentity; / ***Produktbasisklasse*11. Oktober 2016*yiyong_wu*/ Public Class Produkt erweitert DataEntity <produkt> {private statische endgültige lange Serialversionuid = 1L; private String ProductName; privater Schwimmerpreis; private String productNo; public String getProductName () {return productName; } public void setProductName (String productName) {this.ProductName = productName; } public float getPrice () {Rückgabepreis; } public void setprice (float price) {this.price = price; } public String getProductno () {return productNo; } public void setProductno (String productNo) {this.Productno = productNo; }}Wie wäre es damit? Sehen Sie eine sehr komplexe Vererbungsbeziehung? Aber was ist da? Je komplexer es ist, desto vollständiger wird es sein. Als nächstes werde ich mir die Ebene ansehen, dieselben drei Schichten, die bereit sind, getauft zu werden
Basierendao.java reservierte Schnittstelle
Paket com.store.base.secondModel.base; / ** * Top-most-Dao-Schnittstelle * @Author yiyong_wu * */ public interface-basierte {} cruddao.java Eine Dao-Schnittstellenschicht für Addition, Löschung, Änderung und Abfrage [Java] Sehen Sie sich einfaches Kopierdruck an? CODE -Fragmente auf Code anzeigen, die in meinem Code -Fragmentpaket com.store.base.secondModel.base abgeleitet wurden; importieren java.util.list; / ** * DAO -Schnittstelle für Addition, Löschung, Änderung und Abfrage definieren * @author yiyong_wu * * @param <t> */ public interface cruddao <t> erweitert basiertAo {/ ** * ein einzelnes Datenstück * @param id * @return */ public t Get (String id); / ** * Holen Sie sich ein einzelnes Datenstück * @param entity * @Return */ public t Get (t Entity); /*** Abfragen Sie die Datenliste. Wenn Sie Paging benötigen, legen Sie bitte das Paging -Objekt fest, z. B.: entity.setPage (neue Seite <t> ()); * @param entity * @return */ publiclist <T> findlist (t Entity); / ** * alle Datenliste abfragen * @param entity * @return */ publiclist <T> findAlllist (t Entity); /*** alle Datenliste abfragen* @see publiclist <T> findAllList (t Entity)* @return publiclist <T> findAllList (); *// ** * Daten einfügen * @param entity * @return */ public int Insert (t Entity); / ** * Daten aktualisieren * @param entity * @return */ public int update (t Entity); / ** * Daten löschen (normalerweise logische Löschung, aktualisieren Sie das Feld Del_flag auf 1) * @param id * @see public int delete (t Entity) * @return */ public int delete (String -ID); / ** * Daten löschen (normalerweise logische Löschung, aktualisieren Sie das Feld Del_flag auf 1) * @param Entity * @return */ public int delete (t Entity); }Productdao.java mybatis entsprechende Schnittstelle Mapper ist ebenfalls eine DAO -Implementierung. Sie müssen Annotation @mybatisrepository anpassen
Paket com.store.base.secondmodel.pratice.dao; import com.store.base.secondmodel.base.cruddao; import com.store.base.secondmodel.base.mybatisrepository; import com.store.base.secondmodel.pratice.model.product; / ** *Todo *11. Oktober 2016 *yiyong_wu */ @mybatisrepository Public Interface ProductDao erweitert Cruddao <produkts> {}Benutzerdefinierte Annotation mybatisrepository.java ist mit benutzerdefinierter Annotation verbunden. Ich werde hier nicht zu viel erklären, es gibt viele Online -Informationen.
Paket com.store.base.secondModel.base; import Java.lang.Annotation.Documented; importieren java.lang.annotation.retention; importieren java.lang.annotation.target; Import Java.lang.annotation.RetentionPolicy; Import Java.lang.Annotation.Elementtype; import org.springframework.stereotype.comPonent; /*** Identifizieren Sie den DAO von MyBatis, um das Scannen von {@link org.mybatis.spring.mapper.MappersCannerConfiger} zu erleichtern. * *Bitte beachten Sie, dass Sie die Konfiguration so konfigurieren möchten, dass die kommentierte Klasse in der Feder -Konfigurationsdatei scannen * *<bean id = "mapperscannerConfiger"> *Eigentum name = "sqlSessionFactoryBeanname" value = " name="annotationClass" value="com.store.base.secondmodel.base.MyBatisRepository" /> *</bean> * @author yiyong_wu * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Component public @interface MyBatisRepository { String value () Standard ""; } Hinweis: Die Datei productMapper.xml, die eine starke Verbindung mit productDao.java hat, ist die Produktdatei productMapper.xml. Sie können sehen, dass der Namespace der oben genannten Konfigurationsdatei auf den Pfad zu diesem DAO zeigt.
Als nächstes geben wir die endgültige Serviceanalyse ein, und es handelt sich auch um eine dreischichtige Erbschaft.
BaseSeService.java
Paket com.store.base.secondModel.base; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.slf4j.loggerfactory; import org.springframework.transaction.annotation.transactional; / ** * Die übergeordnete Dienstklasse der obersten Ebene * @Author yiyong_wu * */ @transactional (readonly = true) public abstract Class BaseSeService {// Protected Logger logger = loggerfactory.getLogger (getClass ()); }Crudservice.java bezogene Geschäftsschnittstelle Implementierung
Paket com.store.base.secondModel.base; importieren java.util.list; import org.springframework.beans.factory.annotation.autowired; import org.springframework.transaction.annotation.transactional; / ** * Hinzufügen, Löschen, Ändern und Überprüfen der Service -Basisklasse * @Author yiyong_wu * * @param <d> * @param <t> */ public abstract Class CrudService erweitert Cruddao <t>, t expendiert die Datenentwicklung <t >> erweitert das BaseService {/ ** * Persistence -Layer -Objekt */ @ @ @ @ @@autowired DAO; / ** * Erhalten Sie ein einzelnes Datenstück * @param id * @return */ public t get (String id) {return dao.get (id); } / ** * Holen Sie sich ein einzelnes Datenstück * @param entity * @return * / public t Get (t Entity) {return dao.get (Entity); } /** * Query list data* @param entity * @return */ public List<T> findList(T entity) { return dao.findList(entity); } /** * Query paging data* @param page paging object* @param entity * @return */ public Page<T> findPage(Page<T> page, T entity) { entity.setPage(page); page.setList(dao.findList(entity)); return page; } /** * Save data (insert or update) * @param entity */ @Transactional(readOnly = false) public void save(T entity) { if (entity.getIsNewRecord()){ entity.preInsert(); dao.insert(entity); }else{ entity.preUpdate(); dao.update(entity); } } /** * Delete data* @param entity */ @Transactional(readOnly = false) public void delete(T entity) { dao.delete(entity); }}ProductService.java,去继承CrudService接口,注意起注入dao和实体类型的一种模式
package com.store.base.secondmodel.pratice.service; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.store.base.secondmodel.base.CrudService; import com.store.base.secondmodel.pratice.dao.ProductDao; import com.store.base.secondmodel.pratice.model.Product; /** *TODO *2016年10月11日*yiyong_wu */ @Service @Transactional(readOnly = true) public class ProductService extends CrudService<ProductDao,Product>{ }我想看到这里的同志已经很不耐烦了。但是如果你错过接下去的一段,基本上刚才看的就快等于白看了,革命的胜利就在后半段,因为整个分页功能围绕的就是一个Page对象,重磅内容终于要出来了,当你把Page对象填充到刚才那个BaseEntity上的时候,你会发现一切就完整起来了,废话不多说,Page对象如下
package com.store.base.secondmodel.base; import java.io.Serializable; import java.util.ArrayList; importieren java.util.list; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fasterxml.jackson.annotation.JsonIgnore; import com.store.base.secondmodel.base.util.CookieUtils; import com.store.base.secondmodel.base.util.StringUtils; /** * Pagination class* @author yiyong_wu * * @param <T> */ public class Page<T> implements Serializable{ private static final long serialVersionUID = 1L; private int pageNo = 1; // Current page number private int pageSize = Integer.parseInt(Global.getConfig("page.pageSize")); // Page size, set to "-1" means that no paging is performed (paging is invalid) private long count;// Total number of records, set to "-1" means that the total number is not queried private int first;// Home page index private int last;// Last page index private int prev;// Previous page index private int next;// Next page index private boolean firstPage;// Whether it is the first page private boolean lastPage;// Whether it is the last page private int length = 6;// Display page length private int slider = 1;// Display page length before and after private List<T> list = new ArrayList<>(); private String orderBy = ""; // Standard query is valid, example: updated desc, name asc private String funcName = "page"; // Set the name of the js function called by clicking on the page number. The default is page, and it is used when there are multiple paging objects on a page. private String funcParam = ""; // Additional parameter of the function, the third parameter value. private String message = ""; // Set the prompt message, displayed after "n total number of public Page() { this.pageSize = -1; } /** * Constructor method * @param request Pass the repage parameter to remember the page number * @param response is used to set cookies, remember the page number */ public Page(HttpServletRequest request, HttpServletResponse response){ this(request, response, -2); } /** * Constructor method * @param request Pass the repage parameter to remember the page number * @param response is used to set cookies, remember the page number * @param defaultPageSize The default paging size, if -1 is passed, it is not paged, and all data is returned */ public Page(HttpServletRequest request, HttpServletResponse response, int defaultPageSize){ // Set page number parameters (pass repage parameter to remember page number) String no = request.getParameter("pageNo"); if (StringUtils.isNumeric(no)){ CookieUtils.setCookie(response, "pageNo", no); this.setPageNo(Integer.parseInt(no)); }else if (request.getParameter("repage")!=null){ no = CookieUtils.getCookie(request, "pageNo"); if (StringUtils.isNumeric(no)){ this.setPageNo(Integer.parseInt(no)); } } // Set the page size parameter (pass the repage parameter to remember the page size) String size = request.getParameter("pageSize"); if (StringUtils.isNumeric(size)){ CookieUtils.setCookie(response, "pageSize", size); this.setPageSize(Integer.parseInt(size)); }else if (request.getParameter("repage")!=null){ no = CookieUtils.getCookie(request, "pageSize"); if (StringUtils.isNumeric(size)){ this.setPageSize(Integer.parseInt(size)); } }else if (defaultPageSize != -2){ this.pageSize = defaultPageSize; } // Set the sorting parameters String orderBy = request.getParameter("orderBy"); if (StringUtils.isNotBlank(orderBy)){ this.setOrderBy(orderBy); } } /** * Constructor* @param pageNo Current page number* @param pageSize Pagination size*/ public Page(int pageNo, int pageSize) { this(pageNo, pageSize, 0); } /** * Constructor* @param pageNo Current page number* @param pageSize Pagination size* @param count Number of data strips*/ public Page(int pageNo, int pageSize, long count) { this(pageNo, pageSize, count, new ArrayList<T>()); } /** * Constructor* @param pageNo Current page number* @param pageSize Page size* @param count Number of data strips* @param list Data object list on this page*/ public Page(int pageNo, int pageSize, long count, List<T> list) { this.setCount(count); this.setPageNo(pageNo); this.pageSize = pageSize; this.list = list; } /** * Initialization parameter*/ public void initialize(){ //1 this.first = 1; this.last = (int)(count / (this.pageSize < 1 ? 20 : this.pageSize) + first - 1); if (this.count % this.pageSize != 0 || this.last == 0) { this.last++; } if (this.last < this.first) { this.last = this.first; } if (this.pageNo <= 1) { this.pageNo = this.first; this.firstPage=true; } if (this.pageNo >= this.last) { this.pageNo = this.last; this.lastPage=true; } if (this.pageNo < this.last - 1) { this.next = this.pageNo + 1; } else { this.next = this.last; } if (this.pageNo > 1) { this.prev = this.pageNo - 1; } else { this.prev = this.first; } //2 if (this.pageNo < this.first) {// If the current page is smaller than the home page this.pageNo = this.first; } if (this.pageNo > this.last) {// If the current page is larger than the last page this.pageNo = this.last; } } /** * Default output current paging tag* <div>${page}</div> */ @Override public String toString() { StringBuilder sb = new StringBuilder(); if (pageNo == first) {// If it is the home page sb.append("<li class=/"disabled/"><a href=/"javascript:/">« Previous page</a></li>/n"); } else { sb.append("<li><a href=/"javascript:/" onclick=/""+funcName+"("+prev+","+pageSize+",'"+funcParam+"');/">« Previous page</a></li>/n"); } int begin = pageNo - (length / 2); if (begin < first) { begin = first; } int end = begin + length - 1; if (end >= last) { end = last; begin = end - length + 1; if (begin < first) { begin = first; } } if (begin > first) { int i = 0; for (i = first; i < first + slider && i < begin; i++) { sb.append("<li><a href=/"javascript:/" onclick=/""+funcName+"("+i+","+pageSize+",'"+funcParam+"');/">" + (i + 1 - first) + "</a></li>/n"); } if (i < begin) { sb.append("<li class=/"disabled/"><a href=/"javascript:/">...</a></li>/n"); } } for (int i = begin; i <= end; i++) { if (i == pageNo) { sb.append("<li class=/"active/"><a href=/"javascript:/">" + (i + 1 - first) + "</a></li>/n"); } else { sb.append("<li><a href=/"javascript:/" onclick=/"+funcName+"("+i+","+pageSize+",'"+funcParam+"');/">" + (i + 1 - first) + "</a></li>/n"); } } if (last - end > slider) { sb.append("<li class=/"disabled/"><a href=/"javascript:/">...</a></li>/n"); end = last - slider; } for (int i = end + 1; i <= last; i++) { sb.append("<li><a href=/"javascript:/" onclick=/"+funcName+"("+i+","+pageSize+",'"+funcParam+"');/">" + (i + 1 - first) + "</a></li>/n"); } if (pageNo == last) { sb.append("<li class=/"disabled/"><a href=/"javascript:/">Next page»</a></li>/n"); } else { sb.append("<li><a href=/"javascript:/" onclick=/""+funcName+"("+next+","+pageSize+",'"+funcParam+"');/">" + "next page»</a></li>/n"); } return sb.toString(); } /** * Get pagination HTML code* @return */ public String getHtml(){ return toString(); } /** * Get the total number of settings* @return */ public long getCount() { return count; } /** * Set the total number of data* @param count */ public void setCount(long count) { this.count = count; if (pageSize >= count){ pageNo = 1; } } /** * Get the current page number* @return */ public int getPageNo() { return pageNo; } /** * Set the current page number* @param pageNo */ public void setPageNo(int pageNo) { this.pageNo = pageNo; } /** * Get the page size* @return */ public int getPageSize() { return pageSize; } /** * Set page size (maximum 500) // > 500 ? 500 : pageSize; * @param pageSize */ public void setPageSize(int pageSize) { this.pageSize = pageSize <= 0 ? 10 : pageSize; } /** * Home page index* @return */ @JsonIgnore public int getFirst() { return first; } /** * Last page index* @return */ @JsonIgnore public int getLast() { return last; } /** * Get the total number of pages* @return getLast(); */ @JsonIgnore public int getTotalPage() { return getLast(); } /** * Is it the first page* @return */ @JsonIgnore public boolean isFirstPage() { return firstPage; } /** * Is it the last page* @return */ @JsonIgnore public boolean isLastPage() { return lastPage; } /** * Previous page index value* @return */ @JsonIgnore public int getPrev() { if (isFirstPage()) { return pageNo; } else { return pageNo - 1; } } /** * Next page index value* @return */ @JsonIgnore public int getNext() { if (isLastPage()) { return pageNo; } else { return pageNo + 1; } } /** * Get the data object list of this page* @return List<T> */ public List<T> getList() { return list; } /** * Set the data object list of this page* @param list */ public Page<T> setList(List<T> list) { this.list = list; initialisieren(); return this; } /** * Get query sorting string* @return */ @JsonIgnore public String getOrderBy() { // SQL filtering to prevent injection of String reg = "(?:')|(?:--)|(//*(?:.|[//n//r])*?//*/)|" + "(//b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)//b)"; Pattern sqlPattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE); if (sqlPattern.matcher(orderBy).find()) { return ""; } return orderBy; } /** * Set query sorting, standard query is valid, Example: updated desc, name asc */ public void setOrderBy(String orderBy) { this.orderBy = orderBy; } /** * Get the name of the js function called by the click page number* function ${page.funcName}(pageNo){location="${ctx}/list-${category.id}${urlSuffix}?pageNo="+i;} * @return */ @JsonIgnore public String getFuncName() { return funcName; } /** * Set the name of the js function called by the click page number. The default is page, which is used when there are multiple paging objects on a page. * @param funcName Default is page */ public void setFuncName(String funcName) { this.funcName = funcName; } /** * Get additional parameters of the pagination function* @return */ @JsonIgnore public String getFuncParam() { return funcParam; } /** * Set additional parameters of the pagination function* @return */ public void setFuncParam(String funcParam) { this.funcParam = funcParam; } /** * Set the prompt message, displayed after "n total numbers"* @param message */ public void setMessage(String message) { this.message = message; } /** * Is the pagination valid* @return this.pageSize==-1 */ @JsonIgnore public boolean isDisabled() { return this.pageSize==-1; } /** * Whether to count the total number* @return this.count==-1 */ @JsonIgnore public boolean isNotCount() { return this.count==-1; } /** * Get Hibernate FirstResult */ public int getFirstResult() { int firstResult = (getPageNo() - 1) * getPageSize(); if (firstResult >= getCount()) { firstResult = 0; } return firstResult; } /** * Get Hibernate MaxResults */ public int getMaxResults(){ return getPageSize(); }}看完这个Page对象应该稍微有点感觉了吧,然后我在胡乱贴一些相关用到的工具类吧,工具类的话我只稍微提一下,具体大家可以弄到自己的代码上好好解读。
PropertiesLoader.java 用来获取resource文件夹下的常量配置文件
package com.store.base.secondmodel.base.util; import java.io.IOException; import java.io.InputStream; import java.util.NoSuchElementException; import java.util.Properties; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; /** * Properties file loading tool class. Multiple properties files can be loaded, * The value of the same attribute in the last loaded file will overwrite the previous value, but System's Property takes precedence. * @author yiyong_wu * */ public class PropertiesLoader { private static Logger logger = LoggerFactory.getLogger(PropertiesLoader.class); private static ResourceLoader resourceLoader = new DefaultResourceLoader(); private final Properties properties; public PropertiesLoader(String... resourcesPaths) { properties = loadProperties(resourcesPaths); } public Properties getProperties() { return properties; } /** * Take out the Property, but System's Property takes priority, and the empty string cannot be returned. */ private String getValue(String key) { String systemProperty = System.getProperty(key); if (systemProperty != null) { return systemProperty; } if (properties.containsKey(key)) { return properties.getProperty(key); } zurückkehren ""; } /** * Take out the String property, but System's Property takes priority. If all are Null, an exception will be thrown. */ public String getProperty(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return value; } /** * Take out the Property of type String, but the Property of the System is preferred. If it is Null, the Default value will be returned. */ public String getProperty(String key, String defaultValue) { String value = getValue(key); return value != null ? value : defaultValue; } /** * Take out the Property of type Integer, but the Property of the System is preferred. If it is Null or the content is wrong, an exception will be thrown. */ public Integer getInteger(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return Integer.valueOf(value); } /** * Take out the Integer type Property, but the System's Property takes priority. If all are Null, the Default value will be returned, and an exception will be thrown if the content is wrong*/ public Integer getInteger(String key, Integer defaultValue) { String value = getValue(key); return value != null ? Integer.valueOf(value) : defaultValue; } /** * Take out the Double type Property, but the System's Property is preferred. If all are Null or the content is wrong, an exception will be thrown. */ public Double getDouble(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return Double.valueOf(value); } /** * Take out the Double type Property, but the System's Property is preferred. If all are Null, a Default value will be returned. If all are Null, an exception will be thrown. */ public Double getDouble(String key, Integer defaultValue) { String value = getValue(key); return value != null ? Double.valueOf(value) : defaultValue.doubleValue(); } /** * Take out the Property of Boolean type, but the Property of the System is preferred. If all exceptions are thrown for Null, if the content is not true/false, it will return false. */ public Boolean getBoolean(String key) { String value = getValue(key); if (value == null) { throw new NoSuchElementException(); } return Boolean.valueOf(value); } /** * Take out the Boolean type Property, but System's Property takes priority. If all are Null, return the Default value, and if the content is not true/false, return false. */ public Boolean getBoolean(String key, boolean defaultValue) { String value = getValue(key); return value != null ? Boolean.valueOf(value) : defaultValue; } /** * Load multiple files, and the file path uses Spring Resource format. */ private Properties loadProperties(String... resourcesPaths) { Properties props = new Properties(); for (String location : resourcesPaths) { InputStream is = null; try { Resource resource = resourceLoader.getResource(location); is = resource.getInputStream(); props.load(is); } catch (IOException ex) { logger.error("Could not load properties from path:" + location , ex); } finally { IOUtils.closeQuietly(is); } } return props; }}Global.java 用来获取全局的一些常量,可以是从配置文件中读取的常量,也可以是定义成final static的常量,获取配置文件的话是调用上面那个类进行获取的。
package com.store.base.secondmodel.base; import java.io.File; import java.io.IOException; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.DefaultResourceLoader; import com.google.common.collect.Maps; import com.store.base.secondmodel.base.util.PropertiesLoader; import com.store.base.secondmodel.base.util.StringUtils; /** * 全局配置类* @author yiyong_wu * */ public class Global { private static final Logger logger = LoggerFactory.getLogger(Global.class); /** * 当前对象实例*/ private static Global global = new Global(); /** * 保存全局属性值*/ private static Map<String, String> map = Maps.newHashMap(); /** * 属性文件加载对象*/ private static PropertiesLoader loader = new PropertiesLoader("application.properties"); /** * 显示/隐藏public static final String SHOW = "1"; public static final String HIDE = "0"; /** * 是/否*/ public static final String YES = "1"; public static final String NO = "0"; /** * 状态上/下app专用*/ public static final String UPSHVELF = "1"; public static final String DOWNSHVELF = "2"; public static final String SEPARATOR = "/"; /** * 对/错*/ public static final String TRUE = "true"; public static final String FALSE = "false"; /** * 上传文件基础虚拟路径*/ public static final String USERFILES_BASE_URL = "/userfiles/"; /** * 针对富文本编辑器,结尾会产生的空div */ public static final String ENDS = "<p><br></p>"; /** * 默认空的私有构造函数*/ public Global() { //do nothing in this method,just empty } /** * 获取当前对象实例*/ public static Global getInstance() { return global; } /** * 获取配置*/ public static String getConfig(String key) { String value = map.get(key); if (value == null){ value = loader.getProperty(key); map.put(key, value != null ? value : StringUtils.EMPTY); } return value; } /** * 获取URL后缀*/ public static String getUrlSuffix() { return getConfig("urlSuffix"); } /** * 页面获取常量* @see ${fns:getConst('YES')} */ public static Object getConst(String field) { try { return Global.class.getField(field).get(null); } catch (Exception e) { logger.error("获取常量出错", e); } return null; } /** * 获取工程路径* @return */ public static String getProjectPath(){ // 如果配置了工程路径,则直接返回,否则自动获取。 String projectPath = Global.getConfig("projectPath"); if (StringUtils.isNotBlank(projectPath)){ return projectPath; } try { File file = new DefaultResourceLoader().getResource("").getFile(); if (file != null){ while(true){ File f = new File(file.getPath() + File.separator + "src" + File.separator + "main"); if (f == null || f.exists()){ break; } if (file.getParentFile() != null){ file = file.getParentFile(); }else{ break; } } projectPath = file.toString(); } } catch (IOException e) { logger.error("加载配置文件失败", e); } return projectPath; } }CookieUtil.java 从名称就知道是针对获取和存储cookie的一个工具类
package com.store.base.secondmodel.base.util; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Cookie工具类* @author yiyong_wu * */ public class CookieUtils { private static final Logger logger = LoggerFactory.getLogger(CookieUtils.class); /** * 私有构造函数*/ private CookieUtils() { } /** * 设置Cookie(生成时间为1年) * @param name 名称* @param value 值*/ public static void setCookie(HttpServletResponse response, String name, String value) { setCookie(response, name, value, 60*60*24*365); } /** * 设置Cookie * @param name 名称* @param value 值* @param maxAge 生存时间(单位秒) * @param uri 路径*/ public static void setCookie(HttpServletResponse response, String name, String value, String path) { setCookie(response, name, value, path, 60*60*24*365); } /** * 设置Cookie * @param name 名称* @param value 值* @param maxAge 生存时间(单位秒) * @param uri 路径*/ public static void setCookie(HttpServletResponse response, String name, String value, int maxAge) { setCookie(response, name, value, "/", maxAge); } /** * 设置Cookie * @param name 名称* @param value 值* @param maxAge 生存时间(单位秒) * @param uri 路径*/ public static void setCookie(HttpServletResponse response, String name, String value, String path, int maxAge) { Cookie cookie = new Cookie(name, null); cookie.setPath(path); cookie.setMaxAge(maxAge); try { cookie.setValue(URLEncoder.encode(value, "utf-8")); } catch (UnsupportedEncodingException e) { logger.error("不支持的编码", e); } response.addCookie(cookie); } /** * 获得指定Cookie的值* @param name 名称* @return 值*/ public static String getCookie(HttpServletRequest request, String name) { return getCookie(request, null, name, false); } /** * 获得指定Cookie的值,并删除。 * @param name 名称* @return 值*/ public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name) { return getCookie(request, response, name, true); } /** * 获得指定Cookie的值* @param request 请求对象* @param response 响应对象* @param name 名字* @param isRemove 是否移除* @return 值*/ public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name, boolean isRemove) { String value = null; Cookie[] cookies = request.getCookies(); if(cookies == null) { return value; } for (Cookie cookie : cookies) { if (cookie.getName().equals(name)) { try { value = URLDecoder.decode(cookie.getValue(), "utf-8"); } catch (UnsupportedEncodingException e) { logger.error("不支持的编码", e); } if (isRemove) { cookie.setMaxAge(0); response.addCookie(cookie); } } } return value; } }SpringContextHolder.java 主要是用来在java代码中获取当前的ApplicationContext,需要在spring配置文件中配置这个bean并且懒加载设置成false;
package com.store.base.secondmodel.base.util; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @Service @Lazy(false) public class SpringContextHolder implements ApplicationContextAware, DisposableBean { private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class); private static ApplicationContext applicationContext = null; /** * Get the ApplicationContext stored in a static variable. */ public static ApplicationContext getApplicationContext() { assertContextInjected(); return applicationContext; } /** * Get the bean from the static variable applicationContext and automatically transform it into the type of the assigned object. */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) { assertContextInjected(); return (T) applicationContext.getBean(name); } /** * Get the bean from the static variable applicationContext and automatically transform it into the type of the assigned object. */ public static <T> T getBean(Class<T> requiredType) { assertContextInjected(); return applicationContext.getBean(requiredType); } @Override public void destroy() throws Exception { SpringContextHolder.clearHolder(); } /** * Implement the ApplicationContextAware interface and inject the Context into a static variable. */ @Override public void setApplicationContext(ApplicationContext applicationContext) { logger.debug("Inject ApplicationContext to SpringContextHolder:{}", applicationContext); SpringContextHolder.applicationContext = applicationContext; if (SpringContextHolder.applicationContext != null) { logger.info("The ApplicationContext in SpringContextHolder is overwritten, the original ApplicationContext is:" + SpringContextHolder.applicationContext); } } /** * Clear the ApplicationContext in SpringContextHolder to Null. */ public static void clearHolder() { if (logger.isDebugEnabled()){ logger.debug("Clear ApplicationContext in SpringContextHolder:" + applicationContext); } applicationContext = null; } /** * Check that the ApplicationContext is not empty. */ private static void assertContextInjected() { Validate.validState(applicationContext != null, "The applicaitonContext property is not injected, please define SpringContextHolder in applicationContext.xml."); }}StringUtils.java字符串相关的一个工具类
package com.store.base.secondmodel.base.util; import java.io.UnsupportedEncodingException; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.LocaleResolver; import com.store.base.util.Encodes; /** * String help class* @author yiyong_wu * */ public class StringUtils extends org.apache.commons.lang3.StringUtils { private static final char SEPARATOR = '_'; private static final String CHARSET_NAME = "UTF-8"; private static final Logger logger = LoggerFactory.getLogger(StringUtils.class); /** * Convert to byte array* @param str * @return */ public static byte[] getBytes(String str){ if (str != null){ try { return str.getBytes(CHARSET_NAME); } catch (UnsupportedEncodingException e) { logger.error("", e); return new byte[0]; } }else{ return new byte[0]; } } /** * Convert to byte array* @param str * @return */ public static String toString(byte[] bytes){ try { return new String(bytes, CHARSET_NAME); } catch (UnsupportedEncodingException e) { logger.error("", e); return EMPTY; } } /** * Does it contain strings* @param str Verification string* @param strs String group* @return contains return true */ public static boolean inString(String str, String... strs){ if (str != null){ for (String s : strs){ if (str.equals(trim(s))){ return true; }}} return false; } /** * Replace HTML tag method*/ public static String replaceHtml(String html) { if (isBlank(html)){ return ""; } String regEx = "<.+?>"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(html); return m.replaceAll(""); } /** * Replace with HTML recognized by the phone, remove the style and attributes, and keep Enter. * @param html * @return */ public static String replaceMobileHtml(String html){ if (html == null){ return ""; } return html.replaceAll("<([az]+?)//s+?.*?>", "<$1>"); } /** * Replace with HTML recognized by the phone, remove the style and attributes, and keep Enter. * @param txt * @return */ public static String toHtml(String txt){ if (txt == null){ return ""; } return replace(replace(Encodes.escapeHtml(txt), "/n", "<br/>"), "/t", " "); } /** * Thumbnail string (not distinguishing between Chinese and English characters) * @param str Target string* @param length Intercept length* @return */ public static String abbr(String str, int length) { if (str == null) { return ""; } try { StringBuilder sb = new StringBuilder(); int currentLength = 0; for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) { currentLength += String.valueOf(c).getBytes("GBK").length; if (currentLength <= length - 3) { sb.append(c); } else { sb.append("..."); brechen; } } return sb.toString(); } catch (UnsupportedEncodingException e) { logger.error("", e); } zurückkehren ""; } /** * Convert to Double type*/ public static Double toDouble(Object val){ if (val == null){ return 0D; } try { return Double.valueOf(trim(val.toString())); } catch (Exception e) { logger.error("", e); return 0D; } } /** * Convert to Float type*/ public static Float toFloat(Object val){ return toDouble(val).floatValue(); } /** * Convert to Long type*/ public static Long toLong(Object val){ return toDouble(val).longValue(); } /** * Convert to Integer type*/ public static Integer toInteger(Object val){ return toLong(val).intValue(); } /** * Get i18n string*/ public static String getMessage(String code, Object[] args) { LocaleResolver localLocaleResolver = SpringContextHolder.getBean(LocaleResolver.class); HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); Locale localLocale = localLocaleResolver.resolveLocale(request); return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale); } /** * Get the user remote address*/ public static String getRemoteAddr(HttpServletRequest request){ String remoteAddr = request.getHeader("X-Real-IP"); if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("X-Forwarded-For"); } if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("Proxy-Client-IP"); } if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("WL-Proxy-Client-IP"); } return remoteAddr != null ? remoteAddr : request.getRemoteAddr(); } /** * Camel nomenclature tool* @return * toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toCamelCase(String s) { String s1 =s; if (s1 == null) { return null; } s1 = s.toLowerCase(); StringBuilder sb = new StringBuilder(s1.length()); boolean upperCase = false; for (int i = 0; i < s1.length(); i++) { char c = s1.charAt(i); if (c == SEPARATOR) { upperCase = true; } else if (upperCase) { sb.append(Character.toUpperCase(c)); upperCase = false; } else { sb.append(c); } } return sb.toString(); } /** * Camel nomenclature tool* @return * toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toCapitalizeCamelCase(String s) { String s1 = s; if (s1 == null) { return null; } s1 = toCamelCase(s1); return s1.substring(0, 1).toUpperCase() + s1.substring(1); } /** * Camel Nomenclature Tool* @return * toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toUnderScoreCase(String s) { if (s == null) { return null; } StringBuilder sb = new StringBuilder(); boolean upperCase = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); boolean nextUpperCase = true; if (i < (s.length() - 1)) { nextUpperCase = Character.isUpperCase(s.charAt(i + 1)); } if ((i > 0) && Character.isUpperCase(c)) { if (!upperCase || !nextUpperCase) { sb.append(SEPARATOR); } upperCase = true; } else { upperCase = false; } sb.append(Character.toLowerCase(c)); } return sb.toString(); } /** * Convert to JS to get the object value and generate the three-item operation to return the result* @param objectString object string* For example: row.user.id * Return: !row?'':!row.user?'':row.user.id */ public static String jsGetVal(String objectString){ StringBuilder result = new StringBuilder(); StringBuilder val = new StringBuilder(); String[] vals = split(objectString, "."); for (int i=0; i<vals.length; i++){ val.append("." + vals[i]); result.append("!"+(val.substring(1))+"?'':"); } result.append(val.substring(1)); return result.toString(); }}有了上面这些基础的东西,只需要在写一个控制层接口,就可以看到每次返回一个page对象,然后里面封装好了查询对象的列表,并且是按分页得出列表。
package com.store.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.store.base.secondmodel.base.Page; import com.store.base.secondmodel.pratice.model.Product; import com.store.base.secondmodel.pratice.service.ProductService; /** *TODO *October 11, 2016*yiyong_wu */ @RestController @RequestMapping("/product") public class ProductController { @Autowired private ProductService productService; @ResponseBody @RequestMapping(value="/getPageProduct") public Page<Product> getPageProduct(HttpServletRequest request,HttpServletResponse response){ Page<Product> page = productService.findPage(new Page<Product>(request,response), new Product()); return page; }}最后在看一下页面怎么使用这个page对象,这样我们就完整地介绍了这个一个分页功能,代码很多,但很完整。
<%@ page contentType="text/html;charset=UTF-8"%> <%@ include file="/WEB-INF/views/include/taglib.jsp"%> <html> <head> <title></title> <meta name="decorator" content="default" /> function page(n, s) { if (n) $("#pageNo").val(n); if (s) $("#pageSize").val(s); $("#searchForm").attr("action", "${ctx}/app/bank/list"); $("#searchForm").submit(); return false; } </script> </head> <body> <form:form id="searchForm" modelAttribute="XXXX" action="${ctx}/XXX" method="post"> <input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}" /> <input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}" /> <ul> <li> <label>是否上架:</label> <form:select id="status" path="status"> <form:option value="" label=""/> <form:options items="${fns:getDictList('yes_no_app')}" itemLabel="label" itemValue="value" htmlEscape="false"/> </form:select> </li> <li><input id="btnSubmit" type="submit" value="查询"/> <li></li> </ul> </form:form> <sys:message content="${message}" /> <sys:message content="${message}" /> <table id="contentTable"> <thead> <tr> <th>XXXX</th> <th>XXXX</th> <th>XXXX</th> <th>XXXX</th> <th>XXXX</th> <th>XXXX</th> <th>XXXX</th> <th>XXXX</th> </tr> </thead> <tbody> <c:forEach items="${page.list}" var="XXXX"> <tr> <td>${XXXX.name}</td> <td><a href="${ctx}/app/bank/form?id=${XXXX.id}">${XXXX.}</a></td> <td>${XXXX.}</td> <td>${XXXX.}</td> <td>${XXXX.}</td> <td>${fns:getDictLabel(XXXX.isHot, 'yes_no_app', '无')}</td> <td>${XXXX.}</td> <td><c:if test="${XXXX.status==1 }">上架</c:if> <c:if test="${XXXX.status==2 }">下架</c:if> </td> </tr> </c:forEach> </tbody> </table> <div>${page} <li style="padding-top: 6px;padding-left: 12px;float: left;">共${page.count}条</li></div> </body> </html>到这里就基本上把整个分页功能描述得比较清楚了,希望可以帮助到你们快速解决分页这个问题,当然要在前端显示分页漂亮的话要针对li做一些css样式啥的,最后祝福你可以快速掌握这个分页功能!
The above is the skills of the commonly used paging plug-in for Mybatis to implement quick paging. Ich hoffe, es wird für alle hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird allen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!