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

Einfache Methode zur Installation von MySQL unter Linux

Bei der Onlinesuche nach Methoden zur Installatio...

So gehen Sie mit vergessenen Passwörtern in Windows Server 2008 R2 um

Was tun, wenn Sie Windows Server 2008R2 vergessen...

Vue.js verwaltet die Kapselung von Hintergrundtabellenkomponenten

Inhaltsverzeichnis Problemanalyse Warum Kapselung...

Bringen Sie Ihnen bei, wie Sie die Zeigerposition in Javascript erhalten

Die Methode zum Abrufen der Zeigerposition in Jav...

Einfaches Verständnis und Beispiele für MySQL Index Pushdown (ICP)

Vorwort Index Condition Pushdown (ICP) ist eine n...

MySQL-Sortierung – Chinesische Details und Beispiele

Detaillierte Erklärung zur MySQL-Sortierung chine...

Methode zur Erstellung von Vue-Scaffolding-Lernprojekten

1. Was ist Scaffolding? 1. Vue-CLI Vue CLI ist ei...

Detaillierte Erklärung der Beziehung zwischen Vue und VueComponent

Der folgende Fall überprüft die Wissenspunkte der...

Lösung zum Vergessen des Passworts des Pagodenpanels in Linux 3.X/4.x/5.x

Geben Sie ssh ein und geben Sie den folgenden Bef...

Beispiel für die Mosaikierung eines Bildes mit js

Dieser Artikel stellt hauptsächlich ein Beispiel ...

Nginx implementiert ein Codebeispiel für die https-Websitekonfiguration

https-Basisport 443. Er wird für etwas verwendet,...