[ソースコード分析]ソースコードのデバッグMybatis部分

Mybatisソースコード


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


JDBC

例:

	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     }

ここでドライバーを入手

ここに画像の説明を挿入

Mybatisソースコードのフォローアップ

入口としてビルド方法を採用する

ここに画像の説明を挿入

ここに画像の説明を挿入

解析メソッドを入力してください
ここに画像の説明を挿入

parseConfigurationメソッドに入ります
ここに画像の説明を挿入

対応する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>


mapperElementメソッドを入力してください

ここに画像の説明を挿入

XMLでパッケージを構成するとします。
ここに画像の説明を挿入

ここに画像の説明を挿入

マッパーのリソースをxmlで構成するとします

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

configurationElementメソッドを入力してください

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここにparseStatementNodeメソッドを入力して、いくつかの属性を含むノードに関するいくつかの情報を取得します

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

最後にMappedStatementを作成します

ここに画像の説明を挿入

addMappedStatementメソッドを入力します

ここに画像の説明を挿入

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

ここに画像の説明を挿入

ここでは、カプセル化された最終的なMappedStatementオブジェクトがコレクションに追加されていることがわかります。

ここに画像の説明を挿入

これはマッパーコレクションです

ここに画像の説明を挿入

Mapコレクションのキーが同じである場合は上書きされることは誰もが知っていますが、同じマッパーでメソッドを数分で構成するとエラーが報告されます。理由はputメソッドであり、ここで書き換えられます。

ここに画像の説明を挿入

SQLを分析して実行する

getMapperを入力してください

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

InvocationHandlerインターフェースを継承しています

ここに画像の説明を挿入

それでは、彼のinvokeメソッドを見てみましょう
ここに画像の説明を挿入

この実行メソッドを入力してください

ここに画像の説明を挿入

SQLによる処理

ここでselectを使用します。最初に戻り値のタイプを決定します。ここにリストコレクションがあるため、複数あります。

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

構成は次のとおりです

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

静的SQLとして#{}を使用しているため、ここでのSQLは引き続きプレースホルダーを使用していますか?、後でセットで割り当て

ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに画像の説明を挿入

ここに値を設定します

おすすめ

転載: blog.csdn.net/qq_42380734/article/details/108281416