Mybatis implementiert Details zum Abfangen und Ändern von SQL-Abfragen

Mybatis implementiert Details zum Abfangen und Ändern von SQL-Abfragen

Vorwort

Eine der Funktionen eines Interceptors besteht darin, dass wir die Aufrufe bestimmter Methoden abfangen können. Wir können vor und nach der Ausführung dieser abgefangenen Methoden eine Logik hinzufügen oder unsere eigene Logik ausführen, wenn wir diese abgefangenen Methoden ausführen, anstatt die abgefangenen Methoden auszuführen.

Eine der ursprünglichen Absichten beim Entwurf des Mybatis-Interceptors besteht darin, Benutzern zu ermöglichen, zu bestimmten Zeiten ihre eigene Logik zu implementieren, ohne die inhärente Logik von Mybatis ändern zu müssen. Ich möchte beispielsweise einen festen Vorgang für alle SQLs ausführen, Sicherheitsüberprüfungen für SQL-Abfragen durchführen oder zugehörige SQL-Abfrageprotokolle aufzeichnen usw.

Mybatis stellt uns eine Interceptor-Schnittstelle bereit, die einen benutzerdefinierten Interceptor implementieren kann.

 öffentliche Schnittstelle Interceptor {
 Objekt abfangen (Aufrufaufruf) wirft Throwable;
 Objekt-Plugin (Objektziel);
 void setProperties(Eigenschafteneigenschaften);
}

Die Schnittstelle enthält drei Methodendefinitionen

Die Interception-Methode ist eine spezielle Verarbeitungsmethode für das Interception-Objekt. Der übergebene Aufruf enthält die Stärke der Interception-Zielklasse, die Interception-Methode und die Eingabeparametergruppe der Methode. Verwenden Sie das Aufrufverfahren, um die ursprüngliche Funktion auszuführen.

Das Plugin bestimmt, ob abgefangen werden soll. Wenn kein Abfangen erforderlich ist, wird das Ziel direkt zurückgegeben. Wenn ein Abfangen erforderlich ist, wird die statische Wrap-Methode in der Plugin-Klasse aufgerufen. Wenn der aktuelle Interceptor eine Schnittstelle implementiert, wird ein Proxy-Objekt zurückgegeben, andernfalls wird es direkt zurückgegeben (erinnern Sie sich an das Design des Proxy-Modus). Das Proxy-Objekt ist eigentlich eine Instanz der Plugin-Klasse, die die Schnittstelle InvocationHandler implementiert. Die Schnittstelle InvocationHandler enthält nur die Invoke-Methode für die Callback-Methode.

Bei der Ausführung der Interface-Methode des Proxy-Objekts wird die Invoke-Methode des Plugins aufgerufen, welche Objekt, Methode und Parameter zur Ausführung in ein Invocation-Objekt verpackt und an die Intercept-Methode des Interceptors übergibt. Der Aufruf definiert eine verarbeitete Methode zum Ausführen der abgefangenen Originalmethode.

Plugin-Klassendefinition

öffentliche Klasse Plugin implementiert InvocationHandler {
 
 privates Objektziel;
 privater Abfangjäger Abfangjäger;
 private Map, Set> Signaturmap;
 
 privates Plugin(Objektziel, Interceptor Interceptor, Map, Set> SignaturMap) {
  dies.ziel = Ziel;
  dieser.Abfangjäger = Abfangjäger;
  diese.signatureMap = SignaturMap;
 }
 
 öffentliches statisches Objekt Wrap(Objektziel, Interceptor Interceptor) {
  Map, Set> SignaturMap = getSignatureMap(Abfangjäger);
  Klassentyp = Ziel.getClass();
  Klasse[] Schnittstellen = getAllInterfaces(Typ, Signaturkarte);
  if (Schnittstellenlänge > 0) {
   Proxy.newProxyInstance zurückgeben(
     Typ.getClassLoader(),
     Schnittstellen,
     neues Plugin (Ziel, Interceptor, Signaturkarte));
  }
  Rücklaufziel;
 }
 
 öffentliches Objekt aufrufen(Objektproxy, Methode Methode, Objekt[] args) wirft Throwable {
  versuchen {
   Methoden festlegen = signatureMap.get(method.getDeclaringClass());
   if (Methoden != null und Methoden.enthält(Methode)) {
    returniere interceptor.intercept(neuer Aufruf(Ziel, Methode, Argumente));
   }
   Rückgabemethode.Aufrufen (Ziel, Argumente);
  } Fang (Ausnahme e) {
   wirf ExceptionUtil.unwrapThrowable(e);
  }
 }
 
 private statische Karte, Set> getSignatureMap(Interceptor interceptor) {
  Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
  if (interceptsAnnotation == null) { // Problem Nr. 251
   throw new PluginException("Keine @Intercepts-Annotation im Interceptor gefunden " + interceptor.getClass().getName());   
  }
  Signatur[] sigs = interceptsAnnotation.value();
  Map, Set> SignaturMap = neue HashMap, Set>();
  für (Signatur sig : sigs) {
   Methoden festlegen = signatureMap.get(sig.type());
   wenn (Methoden == null) {
    Methoden = neues HashSet();
    signatureMap.put(sig.type(), Methoden);
   }
   versuchen {
    Methode Methode = sig.type().getMethod(sig.method(), sig.args());
    Methoden.add(Methode);
   } Fang (NoSuchMethodException e) {
    throw new PluginException("Methode auf " + sig.type() + " mit dem Namen " + sig.method() + " konnte nicht gefunden werden. Ursache: " + e, e);
   }
  }
  Signaturkarte zurückgeben;
 }
 
 private static Klasse[] getAllInterfaces(Klassentyp, Map, Set> signatureMap) {
  Set> Schnittstellen = neues HashSet>();
  während (Typ != null) {
   für (Klasse c: Typ.getInterfaces()) {
    wenn (signatureMap.containsKey(c)) {
     Schnittstellen.add(c);
    }
   }
   Typ = Typ.getSuperclass();
  }
  gibt Schnittstellen zurück.toArray(neue Klasse[Schnittstellen.Größe()]);
 }
 
}

Die Methode setProperties wird, wie der Name schon sagt, zum Festlegen von Eigenschaften verwendet. Es gibt viele Möglichkeiten, Bean-Eigenschaften zu initialisieren, dies ist eine davon.

Mybatis stellt die Annotation @Intercepts bereit, um zu deklarieren, dass die aktuelle Klasse ein Interceptor ist. Ihr Wert ist ein @Signature-Array, das die Schnittstelle, Methode und den entsprechenden Parametertyp angibt, der abgefangen werden soll.

@Intercepts({@Signature(Methode = "vorbereiten", Typ = StatementHandler.class, Argumente = {Connection.class}),
    @Signature(Methode = "Abfrage", Typ = StatementHandler.class, Argumente = {java.sql.Statement.class, ResultHandler.class})})
öffentliche Klasse TenantInterceptor implementiert Interceptor {
.....

Beispielsweise fängt in der obigen Klassendeklaration die erste Signature-Annotation den Eingabeparameter unter der StatementHandler-Klasse ab, bei der es sich um eine Connection-Methode mit dem Namen „Prepare“ handelt.

Die zweite Signature-Annotation fängt die Abfragemethode in der StatementHandler-Klasse ab, die zwei Eingabeparameter (vom Typ Statement und ResultHandler) enthält.

Schließlich muss der deklarierte Interceptor im Mybatis-Plug registriert werden, damit er wirksam wird.

  <!-- Mybatis konfigurieren -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <Eigenschaftsname="Datenquelle" ref="Datenquelle"/>
    <Eigenschaftsname="Konfigurationsstandort" Wert="Klassenpfad:mybatis/mybatis-config.xml"/>
    <!-- Mapper-Scan -->
    <Eigenschaftsname="mapperLocations" Wert="Klassenpfad:mybatis/*/*.xml"/>
    <Eigenschaftsname="Plugins">
      <Feld>
        <!-- Registrieren Sie Ihren eigenen Interceptor -->
        <bean id="paginationInterceptor" class="xxx.xxx.TenantInterceptor">
        </bean>
      </array>
    </Eigenschaft>
  </bean>

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • So übergeben Sie mehrere Parameter an eine SQL-Abfrage in Mybatis
  • Detaillierte Analyse von SQL-Knoten in Mybatis

<<:  Detaillierte Erläuterung der Schritte zur Verwendung von ElementUI in tatsächlichen Projekten

>>:  Linux-Datenträgerverwaltung – LVM-Nutzung

Artikel empfehlen

Vorteile und Nachteile des MySQL Advanced Learning Index sowie Nutzungsregeln

1. Vor- und Nachteile von Indizes Vorteile: schne...

Was Sie beim Schreiben selbstschließender XHTML-Tags beachten sollten

Das img-Tag in XHTML sollte wie folgt geschrieben...

Zusammenfassung der MySQL-Abfragesyntax

Vorwort: In diesem Artikel wird hauptsächlich die...

Öffnen Sie den Windows-Server-Port (nehmen Sie als Beispiel Port 8080)

Was ist ein Port? Bei den Ports, auf die wir uns ...

Suchmaschinenfreie Sammlung von Website-Einträgen

1: Anmeldeeingang der Baidu-Website Website: http:...

Tiefgreifendes Verständnis der Verwendung von r2dbc in MySQL

Einführung MySQL sollte eine sehr häufig verwende...

Detaillierte Installationshistorie von Ubuntu 20.04 LTS

In diesem Artikel wird die Erstellung einer USB-S...

js realisiert bidirektionale Datenbindung (Accessor-Überwachung)

In diesem Artikelbeispiel wird der spezifische Co...

js, um einen interessanten Countdown-Effekt zu erzielen

js interessanter Countdown-Fall. Zu Ihrer Informa...

JS erkennt den Fall der Eliminierung von Sternen

In diesem Artikelbeispiel wird der spezifische JS...

HTML übertrifft das Implementierungsprinzip und den Code des Textzeilenabfangs

Der HTML-Code zum Abfangen von mehrzeiligem Text l...

Abfrage der Daten des Tages vor dem aktuellen Zeitintervall in MySQL

1. Hintergrund In tatsächlichen Projekten stoßen ...

Erfahren Sie mehr über die am häufigsten verwendeten JavaScript-Ereignisse

Inhaltsverzeichnis JavaScript-Ereignisse: Häufig ...