MyBatis Pagination Einstiegspunkt
In MyBatis gibt es ein Konzept von Plugins (Plugins), was im Wesentlichen eine Interceptor -Idee ist. Die spezifische Analyse finden Sie in der Forschung zum Prinzip von MyBatis Interceptor in einem anderen Artikel. Auf dieser Grundlage zeigt dieser Artikel den Implementierungscode des tatsächlichen Projekts und anderer damit verbundener Analyse direkt an.
Paging spezifische Code -Implementierung
Zunächst können wir Dialekt abstrakte Klasse definieren, um Pagination abstractDialect zu implementieren.java
public abstract class AbstractDialect { / *** Ob Grenze und Offset unterstützt werden* @return* / public abstrakt boolean supportLimitoffset (); / ** * ob die Grenze unterstützt wird * @return */ public abstrakt boolean supportLimit (); / ** * Get SQL nach Hinzufügen von Paging -Attributen * @param sql * @param offset * @param limit * @return */ public abstract String GetLimitString (String SQL, Int Offset, int Limit);}Darüber hinaus werden wir die Seitenpaging -Technologie von Oracle und MySQL -Datenbank separat implementieren.
Mysqldialect.java-Mysql Pagination Dialekt
öffentliche Klasse MySQLDIALECT erweitert AbstractDialect {public boolean SupportSlimitOffset () {return true; } public boolean SupportSlimit () {return true; } public String getLimitString (String SQL, int offset, int limit) {if (offset> 0) {return sql + "limit" + offset + "," + limit; } else {return sql + "limit" + limit; }}}ORACLEDIALECT.JAVA-ORACLE-Dialekt-Implementierung
public class oracledialect erweitert adialect {@Override public boolean SupportLimitoffset () {return false; } @Override public boolean supportLimit () {return false; } @Override public String getLimitString (String SQL, int start, int limit) {if (start <0) {start = 0; } if (limit <0) {limit = 10; } StringBuilder pagesql = new StringBuilder (100); Pagesql.Append ("SELECT * aus (SELECT TEMP. *, ROWNUM row_id von ("); pagesql.append (SQL); pagesql.append (") temp, wobei Rownum <=") .Append (start+limit); pagesql.append (") wobei Row_id>"). return pagesql.toString (); }}Die entsprechende Implementierung des MyBatis-Plug-In-Interceptor-Implementierung lautet wie folgt: Intercept AnweisungHandler#Vorbereitung (Verbindungs-Con), um die SQL-Anweisungsobjektmethode zu erstellen
Paginationsinterceptor.java
@Intercepts ({@signature (type = ansageHandler.class, method = "prepe", args = {connection.class})}) öffentliche Klasse PaginationInterceptor implementiert Interceptor {private endgültige statische Logger log = loggerfactory .getLogger (paginationInterceptor.class); privater Adialect -Dialekt; public void setDialect (adialect Dialekt) {this.dialect = Dialekt; } @Override öffentliches Objekt Intercept (Invocation Invocation) löst Throwable {// das abgefangene Objekt direkt ab, das die Klasse RoutingStatementHandler StatementsHandler = (StatementHandler) Invocation .gettarget () implementiert; BoundSQL boundSQL = StatementHandler.getBoundSQL (); // MetaObject erhalten, das hauptsächlich verwendet wird, um das Objekt und die Attribute zu erhalten, die mit AnweisungHandler MetaObject metastatementHandler = metaObject.forObject (AnweisungHandler, New DefaultObjectFactory (), New DefaultObjectWapperFactory ()) zugeordnet sind. Kartonisch kartoniert = (kartierstatement) metastatementHandler .getValue ("delegate.mappedStatement" .Intern ()); // paginieren Sie nur die Querypagination () -Methode if (mapappstmt.getId (). Indexof ("querypagination") ==-1) {return Invocation.ProSepree (); } // rekonstruieren die Paging SQL String OriginalSQL = (String) metastatementHandler .getValue ("delegate.boundSQL.SQL" .Intern ()); metastatementHandler.setValue ("delegate.boundSql.sql" .Intern (), Dialekt .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 ("Seite SQL:" + bodersql.getSQL ()); Rückgabeaufruf.Proprece (); } // object @Override öffentliches Objekt -Plugin (Objektziel) {return plugin.wrap (target, this); } @Override public void setProperties (Eigenschaften Eigenschaften) {}}Die entsprechende XML -Konfiguration von Feder kann wie folgt sein, wobei die Oracle -Pagination als Beispiel einnimmt
<!-Oracle-Dialektkonfiguration, verwendet für Oracle Pagination-> <bean id = "paginationInterceptor"> <Eigenschaft name = "Dialekt"> <bean/> </property> </bean>
Verwenden Sie den obigen Code und die oben genannte Konfiguration, um den Paginationsvorgang der Oracle -Datenbank und der MySQL -Datenbank abzuschließen. Und der Blogger analysiert einen der Punkte
MyBatis#MetaObject-Metadata-Objektanalyse
Als der Blogger den obigen Code verwendete, war er von der MetaObject -Klasse verwirrt. Es kann direkt alle zugehörigen Eigenschaften des Objekts erhalten, das durch die Methode von GetValue () vervollkommnet wird. Wir können dem Quellcode folgen, um mehr zu erfahren
MetaObject#forObject()
Alle Proxy -Objekte geben diese statische Methode ein
public static metaObject forObject (Object Object, ObjectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {if (Object == null) {return systemmetaObject.null_meta_Object; } else {Neue MetaObject (Objekt, ObjectFactory, ObjectWrapperFactory); }}Wir können den Konstruktor direkt beobachten, hier ist das Geheimnis
private metaObject (Objektobjekt, ObjectFactory ObjectFactory, ObjectWrapperFactory ObjectWrapperFactory) {this.originalObject = Object; this.ObjectFactory = ObjectFactory; this.ObjectWrapperFactory = ObjectWrapperFactory; // Alle Attributakquisitionen werden über die ObjectWrapper -Klasse erhalten. Hier beurteilen wir hauptsächlich den Objekt -Objekttyp, der proxyiert wird, wenn (Objectinformof ObjectWrapper) {this.objectWrapper = (ObjectWrapper) Objekt; } else if (ObjectWrapperFactory.haswrapperfor (Object)) {this.objectWrapper = ObjectWrapperFactory.getWrapperFor (this, Object); } else if (Objectinstanceof map) {this.ObjectWrapper = new mapWrapper (this, (map) Objekt); } else if (ObjectinstanceOf Collection) {this.objectWrapper = new CollectionWrapper (this, (Sammlung) Objekt); } else {// Was wir oft verwenden, ist beanwrapper this.objectwrapper = new BeanWrapper (this, Object); }}Um mehr Infiltrat zu verstehen, verfolgen wir weiter und schließlich haben wir erfuhren, dass es die Konstruktorfunktion der Reflektorklasse aufrufen wird
Private Reflector (Klasse <?> Clazz) {type = clazz; // Erhalten Sie die Konstruktorklasse AddDefaultConstructor (Clazz); // Die Get -Methode -Set -AddgetMethods (Clazz) erhalten; // Die Set -Methode set addSetMethods (clazz); // Die internen Eigenschaftssatz -Addfields (Clazz) erhalten; lesablePropertynames = getMethods.keyset (). TOARRAY (neue String [getMethods.keyset (). size ()]); SetablePropertyNames = setMethods.keyset (). toArray (neue String [setMethods.keyset (). size ()]); für (String propName: lesablePropertynames) {CaseinsensitivPropertyMap.put (propname.touppercase (locale.english), propname); } für (String propName: writablePropertynames) {CaseinsensitivPropertyMap.put (propname.touppercase (locale.english), propname); }} Daraus können wir wissen, dass Sie mit der Reflektor -Proxy -Klasse und dem MetaObject alle Attribute durchqueren können, die der Proxy -Klasse zugeordnet sind. Nehmen Sie RoutingStatementHandler -Klasse als Beispiel. Nach dem obigen Vorgang können Sie auf das interne Attribut -Delegate und die internen Attribute der Delegiertenkonfiguration configuration/objectFactory/typeHandlerRegistry/resultSetHandler/parameterHandler/mappedStatement und andere Attribute zugreifen.
MetaObject#getValue()
Das obige erklärt, wie die internen Eigenschaften der Proxy -Klasse proxy werden. Wir können auch einen kurzen Blick darauf werfen, wie man es richtig nennt.
öffentliches Objekt getValue (String -Name) {// PropertyTokenizer ist ähnlich wie StringTokenizer, außer dass ersterer als Delimiter PropertyTokenizer prop = new PropertyTokenizer (Name) geschrieben wurde; 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); }} Die spezifische Analyse wird hier nicht erklärt. So erhalten Sie die SQL -Zeichenfolge, die von AnweisungHandler gehört, von getValue("delegate.boundSql.sql") und die darin enthaltenen Attribute müssen interne Attribute sein (Fall empfindlich).
MetaObject#setValue()
Das Prinzip ist das gleiche wie MetaObject#getValue() -Methode
Zusammenfassen
Das obige ist das Tutorial zur Verwendung von Spring MyBatis Paging Plug-In, die Ihnen vom Herausgeber vorgestellt wurde. Ich hoffe, es wird Ihnen hilfreich sein. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und der Editor wird Ihnen rechtzeitig antworten. Vielen Dank für Ihre Unterstützung auf der Wulin.com -Website!