[Source code analysis] DEBUG Mybatis part of the source code

Mybatis source code


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


JDBC

Example:

	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     }

Get the driver here

Insert picture description here

Mybatis source code follow-up

Take the build method as the entrance

Insert picture description here

Insert picture description here

Enter the parse method
Insert picture description here

Enter the parseConfiguration method
Insert picture description here

Corresponding mybatis.xml

<?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>


Enter the mapperElement method

Insert picture description here

Suppose we configure pachage in xml
Insert picture description here

Insert picture description here

Suppose we configure the resource of mapper in xml

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Enter the configurationElement method

Insert picture description here

Insert picture description here

Insert picture description here

Enter the parseStatementNode method, here to get some information about the node, including some attributes

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);
  }

Finally construct a MappedStatement

Insert picture description here

Enter the addMappedStatement method

Insert picture description here

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;
}

Insert picture description here

Here we can see the final encapsulated MappedStatement object is added to a collection

Insert picture description here

This is a mapper collection

Insert picture description here

Everyone knows that if the keys of the Map collection are the same, it will be overwritten, but if we configure the methods in the same mapper in multiple minutes, an error will be reported. The reason is the put method, which is rewritten here.

Insert picture description here

Analyze and execute SQL

Enter getMapper

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

It inherits the InvocationHandler interface

Insert picture description here

So let’s take a look at his invoke method
Insert picture description here

Enter this execute method

Insert picture description here

Processing according to sql

I use select here, first determine the type of return value, here is a list collection, so there are multiple

Insert picture description here

Insert picture description here

Insert picture description here

The configuration is as follows

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Since we are using #{} as static SQL, the SQL here still uses placeholders? , Later assigned by set

Insert picture description here

Insert picture description here
Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Insert picture description here

Set the value here

Guess you like

Origin blog.csdn.net/qq_42380734/article/details/108281416