Hintergrund In letzter Zeit werde ich in Interviews häufig nach Datenbanktransaktionen gefragt. Normalerweise weiß ich nur, dass ich die Annotation @Transactional hinzufügen muss, und dann bin ich verwirrt. Ich stelle fest, dass dieser Teil sehr oft übersehen wird, aber Interviewer mögen solche Fragen, die nicht oft gestellt werden, aber sehr wichtig sind, um den Interviewer zu überraschen. Schluss mit dem Unsinn, kommen wir zur Sache. Lösung 1: Aspektprogrammierung @Aspect Diese Lösung umschließt hauptsächlich die Schnittstellenmethoden umgebend unter dem Mapper-Paket und berechnet dann die Zeitdifferenz davor und danach. Dies ist typisches AOP-Wissen. Obwohl diese Berechnung grob ist, ist sie auch eine Lösung. Die konkrete Methode ist wie folgt: @Aspekt @Komponente @Slf4j öffentliche Klasse MapperAspect { @AfterReturning("Ausführung(* cn.xbmchina.mybatissqltime.mapper.*Mapper.*(..))") öffentliche void logServiceAccess(JoinPoint joinPoint) { log.info("Abgeschlossen: " + joinPoint); } /** * Überwachen Sie alle öffentlichen Methoden von cn.xbmchina.mybatissqltime.mapper..*Mapper-Paket und seine Unterpakete*/ @Pointcut("Ausführung(* cn.xbmchina.mybatissqltime.mapper.*Mapper.*(..))") private void PunktSchnittmethode() { } /** * Erklärung zur Benachrichtigung * * @param pjp * @zurückkehren * @throws Wurfobjekt */ @Around("PunktSchnittMethode()") öffentliches Objekt doAround(ProceedingJoinPoint pjp) wirft Throwable { lang begin = System.nanoTime(); Objekt obj = pjp.proceed(); langes Ende = System.nanoTime(); log.info("Aufruf der Mapper-Methode: {}, Parameter: {}, Ausführungszeit: {} Nanosekunden, benötigte Zeit: {} Millisekunden", pjp.getSignature().toString(), Arrays.toString(pjp.getArgs()), (Ende - Anfang), (Ende - Anfang) / 1000000); gibt Objekt zurück; } } Lösung 2: Mybatis-Plugin Bei MyBatis werden Plug-Ins in den Erstellungsprozess der vier Hauptobjekte eingreifen. Das Plug-In kann den dynamischen Proxy-Mechanismus verwenden, um das Zielobjekt Schicht für Schicht zu umschließen und so den Effekt zu erzielen, das Zielobjekt abzufangen, bevor es die Zielmethode ausführt. MyBatis ermöglicht das Abfangen von Aufrufen an bestimmten Punkten während der Ausführung einer zugeordneten Anweisung. Standardmäßig erlaubt MyBatis Plugins, Methodenaufrufe abzufangen, darunter: ①Executor (Aktualisieren, Abfragen, FlushStatements, Commit, Rollback, GetTransaction, Schließen, IsClosed) Hier ist der Code: importiere org.apache.ibatis.executor.statement.StatementHandler; importiere org.apache.ibatis.mapping.BoundSql; importiere org.apache.ibatis.mapping.ParameterMapping; importiere org.apache.ibatis.plugin.Interceptor; importiere org.apache.ibatis.plugin.Intercepts; importiere org.apache.ibatis.plugin.Invocation; importiere org.apache.ibatis.plugin.Plugin; importiere org.apache.ibatis.plugin.Signature; importiere org.apache.ibatis.session.ResultHandler; importiere org.slf4j.Logger; importiere org.slf4j.LoggerFactory; importiere org.springframework.stereotype.Component; importiere java.sql.Statement; importiere java.util.List; importiere java.util.Properties; /** *Interceptor zur Aufzeichnung der SQL-Ausführungszeit* * @author null * 13. Dezember 2019 17:05:28 */ @Intercepts({@Signature(Typ = StatementHandler.Klasse, Methode = "Abfrage", Argumente = {Statement.Klasse, ResultHandler.Klasse}), @Signature(Typ = StatementHandler.class, Methode = "update", Argumente = {Statement.class}), @Signature(Typ = StatementHandler.Klasse, Methode = "Batch", Argumente = {Statement.Klasse})}) @Komponente öffentliche Klasse SqlExecuteTimeCountInterceptor implementiert Interceptor { privater statischer Logger-Logger = LoggerFactory.getLogger(SqlExecuteTimeCountInterceptor.class); /** * Maximale Länge des ausgedruckten Parameterstrings */ private endgültige statische int MAX_PARAM_LENGTH = 50; /** * Maximale SQL-Länge des Datensatzes */ private endgültige statische int MAX_SQL_LENGTH = 200; @Überschreiben öffentliches Objekt abfangen (Aufruf Aufruf) wirft Throwable { Objektziel = Aufruf.getTarget(); lange Startzeit = System.currentTimeMillis(); StatementHandler statementHandler = (StatementHandler) Ziel; versuchen { Aufruf zurückgeben.fortfahren(); Endlich lange endTime = System.currentTimeMillis(); lange Zeitanzahl = Endzeit – Startzeit; BoundSql boundSql = statementHandler.getBoundSql(); : Zeichenfolge sql = boundSql.getSql(); ObjektparameterObject = boundSql.getParameterObject(); Liste<ParameterMapping> parameterMappingList = boundSql.getParameterMappings(); // SQL-Anweisung formatieren, Zeilenumbrüche entfernen und Parameter ersetzen sql = formatSQL(sql, parameterObject, parameterMappingList); logger.info("SQL ausführen: [, {}] Ausführungszeit [{} ms]", sql, timeCount); } } /** * SQL-Anweisungen formatieren/verschönern* * @param sql SQL-Anweisung * @param ParameterObject-Parameter Map * @param parameterMappingList Parameterliste * @return-formatiertes SQL */ privater String formatSQL(String sql, Objekt Parameterobjekt, Liste<ParameterMapping> ParameterMappingList) { // Beurteilung des leeren SQL-Strings bei der Eingabe, wenn (sql == null || sql.length() == 0) { zurückkehren ""; } // SQL verschönern sql = verschönernSql(sql); // In dem Szenario, in dem keine Parameter übergeben werden, verschönern Sie einfach das SQL und geben Sie es zurück, wenn (parameterObject == null || parameterMappingList == null || parameterMappingList.size() == 0) { SQL zurückgeben; } gibt LimitSQLLength(sql) zurück; } /** * Gibt die SQL-Anweisung nach der Längenbeschränkung zurück* * * @param sql ursprüngliche SQL-Anweisung*/ private Zeichenfolge LimitSQLLength(Zeichenfolge sql) { wenn (sql == null || sql.length() == 0) { zurückkehren ""; } wenn (sql.length() > MAX_SQL_LENGTH) { gibt sql.substring(0, MAX_SQL_LENGTH) zurück; } anders { SQL zurückgeben; } } @Überschreiben öffentliches Objekt-Plugin (Objektziel) { gibt Plugin.wrap(Ziel, dies) zurück; } @Überschreiben public void setProperties(Eigenschaften Eigenschaften) { } /** * Ersetzen Sie den entsprechenden Wert in SQL, behalten Sie nur die ersten 50 Zeichen* * @param sql SQL-Anweisung* @param valueOf ? entsprechender Wert*/ privater String Ersetzungswert(String sql, String Wert von) { //Wenn es mehr als 50 Zeichen sind, nimm nur die ersten 50 if (valueOf != null && valueOf.length() > MAX_PARAM_LENGTH) { Wert von = Wert von.Teilzeichenfolge (0, MAX_PARAM_LENGTH); } sql = sql.replaceFirst("\\?", Wert von); SQL zurückgeben; } /** * SQL verschönern * * @param sql SQL-Anweisung */ privater String beautifySql(String sql) { sql = sql.replaceAll("[\\s\n ]+", " "); SQL zurückgeben; } } Lösung 3: Druid direkt verwenden Dies ist die Art von Frage, die wir am häufigsten verwenden, aber in einem Vorstellungsgespräch brauchen Sie sie nur einmal zu sagen, und ich denke, Sie müssen nicht mehr danach fragen. Die Konfigurationsdatei application.yml von Springboot+druid lautet wie folgt: Frühling: Datenquelle: URL: jdbc:mysql://localhost:3306/testdb1?characterEncoding=utf-8&useUnicode=true&useSSL=false&serverTimezone=UTC Treiberklassenname: com.mysql.jdbc.Driver # mysql8.0 und davor wurde com.mysql.jdbc.Driver verwendet Benutzername: root Passwort: root Plattform: MySQL #Durch diese Konfiguration wird der Druidenverbindungspool in unsere Konfiguration eingeführt. Spring wird sein Bestes tun, um den Typ zu bestimmen und dann die Treiberklasse entsprechend der Situation anzupassen. Typ: com.alibaba.druid.pool.DruidDataSource Druide: initial-size: 5 # Initialisierungsgrößemin-idle: 5 # Minimummax-active: 100 # Maximummax-wait: 60000 # Konfigurieren Sie das Timeout für das Warten auf den Verbindungsaufbautime-between-eviction-runs-millis: 60000 # Konfigurieren Sie das Intervall in Millisekunden für die Überprüfung und Erkennung inaktiver Verbindungen, die geschlossen werden müssenmin-evictable-idle-time-millis: 300000 # Geben Sie die Mindestinaktivitätszeit in Millisekunden an, in der eine inaktive Verbindung gelöscht wirdvalidationQuery: select 'x' test-while-idle: true # Ob ein Verbindungstest durchgeführt werden soll, wenn die Verbindung im Leerlauf isttest-on-borrow: false # Ob die Verbindung getestet werden soll, wenn eine Verbindung vom Verbindungspool ausgeliehen wirdtest-on-return: false # Ob die Verbindung getestet werden soll, wenn sie an den Verbindungspool zurückgegeben wirdfilters: config,wall,stat # Filter zum Abfangen von Überwachungsstatistiken konfigurieren. Nach dem Entfernen kann die Überwachungsschnittstelle SQL nicht mehr gezählt werden. „wall“ wird für FirewallpoolPreparedStatements verwendet: true # PSCache einschalten und die Größe von PSCache für jede Verbindung angebenmaxPoolPreparedStatementPerConnectionSize: 20 maxOpenPreparedStatements: 20 # Aktivieren Sie die Funktion mergeSql über die Eigenschaft connectProperties; langsamer SQL-Datensatz connectionProperties: druid.stat.slowSqlMillis=200;druid.stat.logSlowSql=true;config.decrypt=false #Überwachungsdaten aus mehreren DruidDataSources zusammenführen#use-global-data-source-stat: true # WebStatFilter-Konfiguration. Anweisungen finden Sie im Druid Wiki unter „Configuration_Configure WebStatFilter“. Web-Statistik-Filter: aktiviert: true #Ob StatFilter aktiviert werden soll. Der Standardwert ist true. URL-Muster: /* Ausschlüsse: /druid/*,*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico Sitzungsstatistik aktivieren: wahr Sitzungsstatistik-Maximalanzahl: 10 #StatViewServlet-Konfiguration, Anweisungen finden Sie im Druid Wiki, configure_StatViewServletConfigure stat-view-servlet: aktiviert: true #Ob StatViewServlet aktiviert werden soll. Der Standardwert ist true. URL-Muster: /druid/* Reset-Aktivieren: wahr Login-Benutzername: admin Login-Passwort: admin Zusammenfassen 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:
|
<<: JS implementiert Städtelisteneffekt basierend auf VUE-Komponente
· 【Szenenbeschreibung】 Nach HTTP1.1 unterstützt d...
MySql-Batch-Insert-Optimierung. Beispiel für SQL-...
MySQL-Transaktionsisolationsebene anzeigen mysql&...
Vorwort Die Datenbank-Deadlocks, die ich zuvor er...
Inhaltsverzeichnis 1. So erhalten Sie Elemente Ho...
1. Welche drei Formate? Dies sind: gif, jpg und pn...
Ich habe diese Frage heute in der SQL-Schulungsfr...
Installieren Befolgen Sie zur Installation die RE...
Inhaltsverzeichnis Grundlegende Beschreibung AST-...
Der Docker-Container stellt Dienste bereit und la...
Lassen Sie mich zunächst kurz erklären, was MySQL...
1. Schauen Sie sich zunächst die Anforderungskonf...
Installieren Sie die neueste stabile Version von ...
Hier konzentrieren wir uns nur auf die Installati...
Der vollständige Name von Blog sollte Weblog sein...