Mybatis fuente de análisis de análisis sintácticos de módulos: módulo de registro

introducción

mybatis clase de implementación no proporcionó el registro, registro de acceso al tercer componente necesidades

LogFactory bloque estático de código de tercera clase puede ser visto como slf4j registro de prioridad de carga> Apache Commons Registro> log4j2> log4j> julio

  static {
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useSlf4jLogging();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useCommonsLogging();
      }
    });
    tryImplementation(new Runnable() {
      @Override
      public void run() {
        useLog4J2Logging();
      }
    });
	
	// 省略了其他模块的加载逻辑
  }

Como puede verse en nombre de la clase LogFactory utilizado en el patrón de la fábrica, patrón de la fábrica no entiendo se puede ver los siguientes artículos

modo de fábrica (patrón de la fábrica estática, Factory Method, Abstract Factory) Comentarios

Sin embargo, la tercera parte tiene su propio log-log, mybatis adaptador proporciona un modelo unificado de traza, de depuración, advierten, el error de cuatro niveles,

interfaz org.apache.ibatis.logging.Log tiene múltiples clases de implementación, la clase de implementación que es proporcionada por el adaptador mybatis
, por ejemplo Log4jImpl, Log4j2Impl similares, una clase adaptador proporciona una implementación, siguiendo el diagrama de clase UML

Aquí Insertar imagen Descripción

figura Logger encima objetos son org.apache.log4j.Logger, es decir, por la operación de la conversión se interfaz Log4jImpl Log adaptada al objetivo de la operación Logger

diseño adapter sigue varios papeles

  1. Interface Target (Target): Las interfaces de llamantes se pueden utilizar directamente, es decir, la interfaz de registro
  2. Adaptador de clases requeridas (adaptée): Clase adaptée tiene una verdadera lógica, pero la persona que llama no se puede utilizar directamente, ese objeto Logger
  3. Adaptador (adaptador): implementos objetivo la interfaz, embalado objetos adaptée

Por supuesto, por lo general no configurar el objeto Logger después mybatis ajuste en el proyecto, porque el nivel es demasiado bajo, el nivel no son INFO

import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
public static final Log log = LogFactory.getLog(Test.class);

Configurado para dirigir el slf4j

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public static final Logger logger = LoggerFactory.getLogger(Test.class);

Para la adaptación de todos, ya que el módulo de JDBC imprimirá el registro, pero no es vinculante y marco de registro específico, utilizando el objeto de registro después de la adaptación mybatis

JDBC depuración, imprimir diferentes tipos de registros

En mybatis fuente que tiene el paquete de un módulo de registro de JDBC, cuando el nivel de registro a nivel de depuración su salida una gran cantidad de información útil en unos agentes dinámicos modo, como la salida de sentencias SQL, los enlaces de parámetros de usuario que se transmiten, el número de filas y similares afectar a la cuenta de SQL información

Usted podría estar pensando, ¿por qué debería imprimir registro de nivel de depuración a través de proxy dinámico que? Con Log.DEBUG () no en la lista, principalmente para evitar la lógica normal de registro y acoplado a una lógica

BaseJdbcLogger es una clase abstracta que es el padre de otra clase Logger bajo el paquete de JDBC, la herencia siguiente figura
Aquí Insertar imagen Descripción
ConnectionLogger: responsable de la impresión de la información de conexión y las instrucciones SQL, y crear PreparedStatementLogger
PreparedStatementLogger: responsable de imprimir los parámetros, y crear ResultSetLogger
StatementLogger: responsable de imprimir los parámetros información, y crear ResultSetLogger
ResultSetLogger: responsable de la impresión de la información de los resultados de datos

4 clase implementa la idea es la misma , sólo para analizar ConnectionLogger

Cuando el nivel de registro de depurar, devuelve un objeto de conexión después de haber sido proxy, de lo contrario objeto conexión normal

  protected Connection getConnection(Log statementLog) throws SQLException {
    Connection connection = transaction.getConnection();
    if (statementLog.isDebugEnabled()) {
      return ConnectionLogger.newInstance(connection, statementLog, queryStack);
    } else {
      return connection;
    }
  }

objeto ConnectionLogger InvocationHandler implementa la interfaz, el agente devuelve después el objeto de conexión

  public static Connection newInstance(Connection conn, Log statementLog, int queryStack) {
    InvocationHandler handler = new ConnectionLogger(conn, statementLog, queryStack);
    ClassLoader cl = Connection.class.getClassLoader();
    return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
  }

lógica específica interceptación es como sigue

  @Override
  public Object invoke(Object proxy, Method method, Object[] params)
      throws Throwable {
    try {
      // 如果是从Object继承的方法直接忽略
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, params);
      }
      // 如果是调用prepareStatement,prepareCall,createStatement的方法,打印要执行的SQL语句
      // 并返回PreparedStatement的代理对象,让PreparedStatement也具备日志能力,打印参数
      if ("prepareStatement".equals(method.getName())) {
        if (isDebugEnabled()) {
          debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
        }        
        PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
        stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
        return stmt;
      } else if ("prepareCall".equals(method.getName())) {
        if (isDebugEnabled()) {
          debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
        }        
        PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
        stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
        return stmt;
      } else if ("createStatement".equals(method.getName())) {
        Statement stmt = (Statement) method.invoke(connection, params);
        stmt = StatementLogger.newInstance(stmt, statementLog, queryStack);
        return stmt;
      } else {
        return method.invoke(connection, params);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }

Podemos ver los tres métodos se mejoraron prepareStatement, prepareCall, createStatement

Si el método es llamar prepareStatement, prepareCall de, las sentencias SQL que se ejecutará de impresión
tres métodos devolverán un objeto proxy PreparedStatement, por lo PreparedStatement también tienen la capacidad de registrar los parámetros de impresión,

Ver el registro de depuración final impreso

DEBUG 2020-02-24 18:09:13,647 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==>  Preparing: select id, `name`, phone from author 
DEBUG 2020-02-24 18:09:13,766 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: ==> Parameters: 
DEBUG 2020-02-24 18:09:13,813 org.apache.ibatis.logging.jdbc.BaseJdbcLogger: <==      Total: 1

No se veía muy familiarizado, que es usar proxies dinámicos para lograr

atención de bienvenida

Aquí Insertar imagen Descripción

Publicados 385 artículos originales · ganado elogios 1471 · Vistas de 900.000 +

Supongo que te gusta

Origin blog.csdn.net/zzti_erlie/article/details/104398887
Recomendado
Clasificación