[Análisis del código fuente] DEBUG Mybat es parte del código fuente

Código fuente de Mybatis


声明:此过程仅记录本人DEBUG过程,如有错误请指出!


JDBC

Ejemplo:

	public class JDBCTest {
    
    
 12     
 13     public static void jdbcDemoSelect(String driver,String url,String user,String password) throws Exception {
    
    
 14         
 15         //1.加载类驱动
 16         Class.forName(driver);
 17         Connection con = DriverManager.getConnection(url,user,password);
 18     
 19 //        if(!con.isClosed())
 20 //            System.out.println("succeeded connection to the database");
 21         
 22         //2.创建statement类对象,用来执行SQL语句
 23         Statement statement = con.createStatement();
 24         
 25         //SQL语句
 26         String sql = "select * from emp";    
 27         
 28         //3.ResultSet类,用来存放获取的结果集
 29         ResultSet set = statement.executeQuery(sql);
 30         
 31         String eid=null,ename=null,price=null;
 32         
 33         while(set.next()) {
    
    
 34             eid = set.getString("eid");
 35             ename = set.getString("ename");
 36             price = set.getString("price");
 37             
 38             System.out.println(eid+"\t"+ename+"\t"+price);
 39         }
 40         
 41     }

Obtenga el conductor aquí

Inserte la descripción de la imagen aquí

Seguimiento del código fuente de Mybatis

Toma el método de construcción como entrada

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Ingrese el método de análisis
Inserte la descripción de la imagen aquí

Ingrese el método parseConfiguration
Inserte la descripción de la imagen aquí

Mybatis.xml correspondiente

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <!-- 别名 -->
    <typeAliases>
        <!-- <typeAlias type="com.test.pojo.People" alias="po" /> -->
        <package name="com.lmy.pojo" />
    </typeAliases>

    <environments default="default">
        <environment id="default">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/usermanager?autoReconnect=true&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="121891"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- <mapper resource="com/test/mapper/StudentMapper.xml" />
        <mapper resource="com/test/mapper/TeacherMapper.xml" /> -->
        <!--<mapper class="com.test.mapper.TeacherMapper" />-->
        <package name="com.lmy.mapper"/>
    </mappers>

</configuration>


Ingrese el método mapperElement

Inserte la descripción de la imagen aquí

Supongamos que configuramos pachage en xml
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Supongamos que configuramos el recurso de mapeador en xml

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Ingrese el método configurationElement

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Ingrese el método parseStatementNode, aquí para obtener información sobre el nodo, incluidos algunos atributos

public void parseStatementNode() {
    
    
    String id = context.getStringAttribute("id");
    String databaseId = context.getStringAttribute("databaseId");

    if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) return;

    Integer fetchSize = context.getIntAttribute("fetchSize");
    Integer timeout = context.getIntAttribute("timeout");
    String parameterMap = context.getStringAttribute("parameterMap");
    String parameterType = context.getStringAttribute("parameterType");
    Class<?> parameterTypeClass = resolveClass(parameterType);
    String resultMap = context.getStringAttribute("resultMap");
    String resultType = context.getStringAttribute("resultType");
    String lang = context.getStringAttribute("lang");
    LanguageDriver langDriver = getLanguageDriver(lang);

    Class<?> resultTypeClass = resolveClass(resultType);
    String resultSetType = context.getStringAttribute("resultSetType");
    StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
    ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);

    String nodeName = context.getNode().getNodeName();
    SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
    boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
    boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
    boolean useCache = context.getBooleanAttribute("useCache", isSelect);
    boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);

    // Include Fragments before parsing
    XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
    includeParser.applyIncludes(context.getNode());

    // Parse selectKey after includes and remove them.
    processSelectKeyNodes(id, parameterTypeClass, langDriver);
    
    // Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
    SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
    String resultSets = context.getStringAttribute("resultSets");
    String keyProperty = context.getStringAttribute("keyProperty");
    String keyColumn = context.getStringAttribute("keyColumn");
    KeyGenerator keyGenerator;
    String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
    keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
    if (configuration.hasKeyGenerator(keyStatementId)) {
    
    
      keyGenerator = configuration.getKeyGenerator(keyStatementId);
    } else {
    
    
      keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
          configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
          ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
    }

    builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
        fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
        resultSetTypeEnum, flushCache, useCache, resultOrdered, 
        keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
  }

Finalmente construya un MappedStatement

Inserte la descripción de la imagen aquí

Ingrese el método addMappedStatement

Inserte la descripción de la imagen aquí

public MappedStatement addMappedStatement(
    String id,
    SqlSource sqlSource,
    StatementType statementType,
    SqlCommandType sqlCommandType,
    Integer fetchSize,
    Integer timeout,
    String parameterMap,
    Class<?> parameterType,
    String resultMap,
    Class<?> resultType,
    ResultSetType resultSetType,
    boolean flushCache,
    boolean useCache,
    boolean resultOrdered,
    KeyGenerator keyGenerator,
    String keyProperty,
    String keyColumn,
    String databaseId,
    LanguageDriver lang,
    String resultSets) {
  
  if (unresolvedCacheRef) throw new IncompleteElementException("Cache-ref not yet resolved");
  
  id = applyCurrentNamespace(id, false);
  boolean isSelect = sqlCommandType == SqlCommandType.SELECT;

  MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
  statementBuilder.resource(resource);
  statementBuilder.fetchSize(fetchSize);
  statementBuilder.statementType(statementType);
  statementBuilder.keyGenerator(keyGenerator);
  statementBuilder.keyProperty(keyProperty);
  statementBuilder.keyColumn(keyColumn);
  statementBuilder.databaseId(databaseId);
  statementBuilder.lang(lang);
  statementBuilder.resultOrdered(resultOrdered);
  statementBuilder.resulSets(resultSets);
  setStatementTimeout(timeout, statementBuilder);

  setStatementParameterMap(parameterMap, parameterType, statementBuilder);
  setStatementResultMap(resultMap, resultType, resultSetType, statementBuilder);
  setStatementCache(isSelect, flushCache, useCache, currentCache, statementBuilder);

  MappedStatement statement = statementBuilder.build();
  configuration.addMappedStatement(statement);
  return statement;
}

Inserte la descripción de la imagen aquí

Aquí podemos ver que el objeto MappedStatement encapsulado final se agrega a una colección

Inserte la descripción de la imagen aquí

Esta es una colección de mapeadores

Inserte la descripción de la imagen aquí

Todo el mundo sabe que si las claves de la colección Map son iguales se sobrescribirá, pero si configuramos los métodos en el mismo mapeador en varios minutos se reportará un error, el motivo es el método put, que aquí se reescribe.

Inserte la descripción de la imagen aquí

Analizar y ejecutar SQL

Ingrese getMapper

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Hereda la interfaz InvocationHandler

Inserte la descripción de la imagen aquí

Así que echemos un vistazo a su método de invocación.
Inserte la descripción de la imagen aquí

Ingrese este método de ejecución

Inserte la descripción de la imagen aquí

Procesamiento según sql

Yo uso seleccionar aquí, primero determine el tipo de valor de retorno, aquí hay una colección de lista, por lo que hay múltiples

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

La configuración es la siguiente

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Dado que estamos usando # {} como SQL estático, ¿el SQL aquí todavía usa marcadores de posición? , Posteriormente asignado por set

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Establecer el valor aquí

Supongo que te gusta

Origin blog.csdn.net/qq_42380734/article/details/108281416
Recomendado
Clasificación