Análise inicial do código-fonte do Mybatis (1)

O guia do código fonte do mybatis que está há muito tempo deixado de lado, hoje darei um pequeno resumo.
Ler o código fonte? Acho que deve ser feito na ordem de macro para micro. Se necessário, você pode até adicionar seu próprio processo gráfico para deixar suas ideias mais claras.

Primeiras reflexões sobre mybatis

  1. Em primeiro lugar, mybatis é uma estrutura para simplificar as operações.
  2. Então sua existência substitui a conexão jdbc, portanto deve incluir as operações básicas de conexão ao banco de dados.

Sobre a operação do jdbc

package jdbc;

import java.sql.*;
/**
 * @Author:XK
 * @Date: Created in 17:48 2021/10/26
 * @Description:jdbc的简单实现
 **/
public class jdbcFirstDemo {
    
    
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
    
    
        //1加载驱动
        Class.forName("com.mysql.jdbc.Driver");

        //2用户信息和URL
        String url ="jdbc:mysql://localhost:3306/fisrt21?useUnicod=true&characterEncoding=utf8&useSSL=true";
        String username="root";
        String password = "2020";

        //3连接成功 获取到数据库对象,Connection
        Connection connection = DriverManager.getConnection(url,username,password);

        //4.执行sql对象statement 执行sql的对象
        Statement statement = connection.createStatement();

        // 5 . 执行sql对象之后返回的结果集 Resultset
        String sql ="select * from class";

        ResultSet resultSet= statement.executeQuery(sql);

        while (resultSet.next()){
    
    
            System.out.println(resultSet.getString("class_name"));
        }

        //6 释放连接
        resultSet.close();
        statement.close();
        connection.close();

    }
}

Acho que existem três partes: fonte de dados, instrução SQL e operação de dados.

  • A fonte de dados aqui é uma configuração que inclui URL, nome de usuário e senha. Através disso você pode se conectar ao banco de dados
  • A instrução sql é uma instrução sql que escrevi manualmente
  • A operação de dados é o processo no qual meu objeto de banco de dados de conexão obtém a instrução do objeto SQL e, em seguida, executa a instrução SQL por meio da instrução para obter um conjunto de resultados.
    Esta é uma operação de conexão de banco de dados jdbc que considero muito básica.

Como o framework mybats substitui a conexão jdbc, ele também deve concluir essas três tarefas, e a ordem é semelhante. Se está correto ou não, precisa ser verificado no código-fonte. Aí peguei essa dúvida e entrei na leitura do código fonte.

Primeira leitura do código fonte do mabatis

Não sei como os outros leem um código-fonte. Para mim, apenas escrevo uma demonstração e depois passo pelo processo de depuração da ideia para ver passo a passo que tipo de processo é esse framework. Por meio do documento oficial do mybatis, Documento
oficial do mybatis e extraia o código-fonte do mybatis do GitHub.

package test1;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import javax.sound.sampled.Line;
import java.io.IOException;
import java.io.InputStream;


/**
 * @Author:XK
 * @Date: Created in 16:25 2022/4/3
 * @Description:
 **/
public class demo {
    
    
  public static void main(String[] args) throws IOException {
    
    
    String resource = "resources/mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    sqlSession.getMapper(UsrMapper.class).selectAll();
  }
}

Escreva uma pequena demonstração para começar a analisar.
Em primeiro lugar, a partir da primeira linha de código, converta a configuração de config.xml em inputstream e, em seguida, execute a construção de um método sqlsessionFactory. Qualquer pessoa familiarizada com mybatis sabe que todo
aplicativo baseado em MyBatis é centrado em uma instância de SqlSessionFactory. Instâncias de SqlSessionFactory podem ser obtidas por meio de SqlSessionFactoryBuilder. O SqlSessionFactoryBuilder pode criar uma instância SqlSessionFactory a partir de um arquivo de configuração XML ou de uma instância de configuração pré-configurada.
Esta etapa consiste em construir uma instância de SqlSessionFactory por meio da análise de config.xml e é exclusiva.

Vamos ver quais pontos são construídos no método build.

 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    
    
    try {
    
    
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
    
    
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
    
    
      ErrorContext.instance().reset();
      try {
    
    
        inputStream.close();
      } catch (IOException e) {
    
    
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

Obviamente, existe uma classe XMLConfigBuilder. Pelo nome da classe, posso adivinhar aproximadamente para que serve isso. Provavelmente é uma classe de ferramenta usada para analisar arquivos XML. Obviamente, um método XMLConfigBuilder.parse() é executado antes da construção. Clique para ver

  public Configuration parse() {
    
    
    if (parsed) {
    
    
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

  private void parseConfiguration(XNode root) {
    
    
    try {
    
    
      // issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      loadCustomLogImpl(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
    
    
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

O método parseConfiguration é chamado para analisar a configuração.
Vamos dar uma olhada em alguns métodos específicos. Os que estou familiarizado são mapeadores de ambientes, etc. Clique em ambientesElement

  private void environmentsElement(XNode context) throws Exception {
    
    
    if (context != null) {
    
    
      if (environment == null) {
    
    
        environment = context.getStringAttribute("default");
      }
      for (XNode child : context.getChildren()) {
    
    
        String id = child.getStringAttribute("id");
        if (isSpecifiedEnvironment(id)) {
    
    
          TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
          DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
          DataSource dataSource = dsFactory.getDataSource();
          Environment.Builder environmentBuilder = new Environment.Builder(id)
              .transactionFactory(txFactory)
              .dataSource(dataSource);
          configuration.setEnvironment(environmentBuilder.build());
          break;
        }
      }
    }
  }

A partir deste código podemos ver que cada campo corresponde a uma classe, por exemplo, ambientes corresponde a uma classe de ambiente.

public final class Environment {
    
    
  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;
  }

Os campos aqui correspondem à configuração do config.xml

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/fisrt21?useUnicod=true&amp;characterEncoding=utf-8&amp;useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="2020"/>
            </dataSource>
        </environment>
    </environments>

Você pode ver que depois de finalmente obter o valor, um setup.setXXXX será executado. Então, o que exatamente é essa configuração?

  protected Environment environment;

  protected boolean safeRowBoundsEnabled;
  protected boolean safeResultHandlerEnabled = true;
  protected boolean mapUnderscoreToCamelCase;
  protected boolean aggressiveLazyLoading;
  protected boolean multipleResultSetsEnabled = true;
  protected boolean useGeneratedKeys;
  protected boolean useColumnLabel = true;
  protected boolean cacheEnabled = true;
  protected boolean callSettersOnNulls;
  protected boolean useActualParamName = true;
  protected boolean returnInstanceForEmptyRow;
  protected boolean shrinkWhitespacesInSql;
  protected boolean nullableOnForEach;

Descobri que ele contém uma série de parâmetros de configuração, então acho que contém algumas camadas de configuração do mybatis.
Nesse processo, ele lê todas as configurações do arquivo xml na instância da classe de configuração e
executa a construção após a conclusão.

  public SqlSessionFactory build(Configuration config) {
    
    
    return new DefaultSqlSessionFactory(config);
  }

Você pode ver que um DefaultSqlSessionFactory é retornado. O SqlSessionFactory padrão possui métodos selectone ou getmapper. A partir disso, pode-se ver que uma instância do SqlSessionFactory principal deste aplicativo mybatis foi criada. Confirmei minha suspeita.
Em primeiro lugar, o ambiente em config.xml é uma url, assim como a configuração de nome de usuário e senha.
Portanto, pode-se dizer que esta etapa cria uma fonte de dados. A próxima etapa é descobrir como a instrução SQL é obtida.

Análise preliminar do código-fonte do Mybatis (2)

Acho que você gosta

Origin blog.csdn.net/Yoke______/article/details/123956039
Recomendado
Clasificación