• Mybatis源码的理解


    0.核心的包

    在这里插入图片描述# 1.Configuration类

    1.1 配置文件mybatis-config.xml

    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "https://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    
        
        <properties resource="db.properties">properties>
     
        <settings>
            
            <setting name="logImpl" value="STDOUT_LOGGING"/>
            
            <setting name="cacheEnabled" value="true"/>
        settings>
        
        <environments default="development">
            <environment id="development">
                  <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                dataSource>
            environment>
        environments>
        <mappers>
            <mapper resource="mapper/PersonMapper.xml"/>
        mappers>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1.2 配置文件解析

    将配置文件转化为输入流,最终将 xml转化Configuration类.

    将配置文件转化为输入流,将 xml转化Configuration类.

    //XMLConfigBuilder  解析器
    XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
    //将xml转化为Document
    public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
        commonConstructor(validation, variables, entityResolver);
        this.document = createDocument(new InputSource(inputStream));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    解析配置对应的标签为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);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    Configuration的核心类的属性

    public class Configuration {
      //加载环境
      protected Environment environment;
      //是否开启缓存
      protected boolean cacheEnabled = true;
      //配置日志的实现
      protected Class<? extends Log> logImpl;
      //配置属性Properties 
      protected Properties variables = new Properties();
      protected ObjectFactory objectFactory = new DefaultObjectFactory();
      protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
      ///代理工厂 
      protected ProxyFactory proxyFactory = new JavassistProxyFactory();
      //数据库ID
      protected String databaseId;
      //mapper注册
      protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
      //拦截器注册类
      protected final InterceptorChain interceptorChain = new InterceptorChain();
      //类型处理器
      protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry(this);
      //类别名注册
      protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
    //加载映射的mapper xml
      protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>(
          "Mapped Statements collection")
              .conflictMessageProducer((savedValue, targetValue) -> ". please check " + savedValue.getResource() + " and "
                  + targetValue.getResource());
     //加载的缓存
      protected final Map<String, Cache> caches = new StrictMap<>("Caches collection");
      //xml结果集
      protected final Map<String, ResultMap> resultMaps = new StrictMap<>("Result Maps collection");
      //参数的
      protected final Map<String, ParameterMap> parameterMaps = new StrictMap<>("Parameter Maps collection");
      //主键生成器 
      protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<>("Key Generators collection");
      ///sql片段
      protected final Map<String, XNode> sqlFragments = new StrictMap<>("XML fragments parsed from previous mappers");
    
    
      public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject,
          BoundSql boundSql) {
        ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement,
            parameterObject, boundSql);
        return (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
      }
    // ResultSetHandler  结果集处理
      public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds,
          ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql) {
        ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler,
            resultHandler, boundSql, rowBounds);
        return (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
      }
    
      public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement,
          Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject,
            rowBounds, resultHandler, boundSql);
        return (StatementHandler) interceptorChain.pluginAll(statementHandler);
      }
    
      public Executor newExecutor(Transaction transaction) {
        return newExecutor(transaction, defaultExecutorType);
      }
      //获取执行器
      public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
          executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
          executor = new ReuseExecutor(this, transaction);
        } else {
          executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
          executor = new CachingExecutor(executor);
        }
        return (Executor) interceptorChain.pluginAll(executor);
      }
    
      //获取注册mapper类
      public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    1.3 解析完成查询之后的configuration

    public Configuration parse() {
        if (parsed) {
          throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        }
        parsed = true;
        parseConfiguration(parser.evalNode("/configuration"));
        return configuration;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    environment类

    环境类

    sqlFragments类

    sqlFragments

    mapperRegistry类

    mapperRegistry

    mapperStatements

    mappedStatements

    caches类

    resultMaps

    2.SQL解析

    sql的解析有两种,一个是标签注解,一个是xml配置文件的解析。对应的映射解析器为XMLMapperBuilder和MapperAnnotationBuilder

    2.1 XMLMapperBuilder

    属性

     private final XPathParser parser;
     //辅助构建类
     private final MapperBuilderAssistant builderAssistant;
     //加载的sql片段
     private final Map<String, XNode> sqlFragments;
     private final String resource;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    解析文件的mapper的命名空间,缓存,参数,结果集以及sql.

    private void configurationElement(XNode context) {
        try {
          String namespace = context.getStringAttribute("namespace");
          if (namespace == null || namespace.isEmpty()) {
            throw new BuilderException("Mapper's namespace cannot be empty");
          }
          builderAssistant.setCurrentNamespace(namespace);
          cacheRefElement(context.evalNode("cache-ref"));
          cacheElement(context.evalNode("cache"));
          parameterMapElement(context.evalNodes("/mapper/parameterMap"));
          resultMapElements(context.evalNodes("/mapper/resultMap"));
          sqlElement(context.evalNodes("/mapper/sql"));
          buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
        } catch (Exception e) {
          throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    解析参数parameterMap

    private void parameterMapElement(List<XNode> list) {
        for (XNode parameterMapNode : list) {
          String id = parameterMapNode.getStringAttribute("id");
          String type = parameterMapNode.getStringAttribute("type");
          Class<?> parameterClass = resolveClass(type);
          List<XNode> parameterNodes = parameterMapNode.evalNodes("parameter");
          List<ParameterMapping> parameterMappings = new ArrayList<>();
          for (XNode parameterNode : parameterNodes) {
            String property = parameterNode.getStringAttribute("property");
            String javaType = parameterNode.getStringAttribute("javaType");
            String jdbcType = parameterNode.getStringAttribute("jdbcType");
            String resultMap = parameterNode.getStringAttribute("resultMap");
            String mode = parameterNode.getStringAttribute("mode");
            String typeHandler = parameterNode.getStringAttribute("typeHandler");
            Integer numericScale = parameterNode.getIntAttribute("numericScale");
            ParameterMode modeEnum = resolveParameterMode(mode);
            Class<?> javaTypeClass = resolveClass(javaType);
            JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
            Class<? extends TypeHandler<?>> typeHandlerClass = resolveClass(typeHandler);
            ParameterMapping parameterMapping = builderAssistant.buildParameterMapping(parameterClass, property, javaTypeClass, jdbcTypeEnum, resultMap, modeEnum, typeHandlerClass, numericScale);
            parameterMappings.add(parameterMapping);
          }
          builderAssistant.addParameterMap(id, parameterClass, parameterMappings);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    解析sql片段

    sqlfragment

    2.2 MapperAnnotationBuilder

    3. SQL执行:

    3.1 获取SqlSession 以及获取执行器

     private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level,
          boolean autoCommit) {
        Transaction tx = null;
        try {
          final Environment environment = configuration.getEnvironment();
          final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
          tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
          final Executor executor = configuration.newExecutor(tx, execType);
          return new DefaultSqlSession(configuration, executor, autoCommit);
        } catch (Exception e) {
          closeTransaction(tx); // may have fetched a connection so lets call close()
          throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
        } finally {
          ErrorContext.instance().reset();
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.2 Executor【SimpleExecutor ReuseExecutor】

    接口–》Executor --》 SimpleExecutor ReuseExecutor 【Statement–JDBC】

    executorType类型

    public enum ExecutorType {
      SIMPLE,
      REUSE,
      BATCH
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    根据类型获取执行器

    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
          executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
          executor = new ReuseExecutor(this, transaction);
        } else {
          executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
          executor = new CachingExecutor(executor);
        }
        return (Executor) interceptorChain.pluginAll(executor);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    执行sql语句

    执行

    从配置文件拿到执行的语句

      private <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
        try {
          MappedStatement ms = configuration.getMappedStatement(statement);
          dirty |= ms.isDirtySelect();
          return executor.query(ms, wrapCollection(parameter), rowBounds, handler);
        } catch (Exception e) {
          throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
        } finally {
          ErrorContext.instance().reset();
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    执行器

    绑定sql

      public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
          ResultHandler resultHandler, BoundSql boundSql) {
    
        switch (ms.getStatementType()) {
          case STATEMENT:
            delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
            break;
          case PREPARED:
            delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
            break;
          case CALLABLE:
            delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
            break;
          default:
            throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
        }
    
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    jdbc执行

    在这里插入图片描述

    mysql执行

    4. 结果映射:ResultSetHandler

    4.1 执行拿到返回结果进行处理

      @Override
      public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
        PreparedStatement ps = (PreparedStatement) statement;
        ps.execute();
        return resultSetHandler.handleResultSets(ps);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    执行返回的数据

    最终返回的

    4.2 resultSetHandler.handleResultSets(ps)

    结果处理

     public List<Object> handleResultSets(Statement stmt) throws SQLException {
        ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
    
        final List<Object> multipleResults = new ArrayList<>();
    
        int resultSetCount = 0;
        ResultSetWrapper rsw = getFirstResultSet(stmt);
    
        List<ResultMap> resultMaps = mappedStatement.getResultMaps();
        int resultMapCount = resultMaps.size();
        validateResultMapsCount(rsw, resultMapCount);
        while (rsw != null && resultMapCount > resultSetCount) {
          ResultMap resultMap = resultMaps.get(resultSetCount);
          handleResultSet(rsw, resultMap, multipleResults, null);
          rsw = getNextResultSet(stmt);
          cleanUpAfterHandlingResultSet();
          resultSetCount++;
        }
    
        String[] resultSets = mappedStatement.getResultSets();
        if (resultSets != null) {
          while (rsw != null && resultSetCount < resultSets.length) {
            ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
            if (parentMapping != null) {
              String nestedResultMapId = parentMapping.getNestedResultMapId();
              ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
              handleResultSet(rsw, resultMap, null, parentMapping);
            }
            rsw = getNextResultSet(stmt);
            cleanUpAfterHandlingResultSet();
            resultSetCount++;
          }
        }
    
        return collapseSingleResultList(multipleResults);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    一键启动的AI离线知识库,无需复杂环境依赖,小白都能上手了
    深入理解 Nginx 的负载均衡与反向代理
    蒲公英路由器如何设置远程打印?
    vue-electron 项目创建记录及注意事项
    守护线程?
    java计算机毕业设计科研成果管理系统设计与实现MyBatis+系统+LW文档+源码+调试部署
    JVM笔记(一)内存模型
    FPGA+金融|硬件行情加速系统 打造极速交易场景
    Helm部署EMQX集群
    sql:SQL优化知识点记录(十三)
  • 原文地址:https://blog.csdn.net/qq_37400096/article/details/130835486