• Mybaits源码分析六之XMLConfigBuilder类 environments标签解析


    根据mybatis配置加载流程 

     1 private void parseConfiguration(XNode root) {
     2     try {
     3       //解析子节点的properties文件
     4       propertiesElement(root.evalNode("properties"));
     5       //加载用户自定义配置
     6       Properties settings = settingsAsProperties(root.evalNode("settings"));
     7       //加载vfs虚拟文件系统配置
     8       loadCustomVfs(settings);
     9      // 解析子节点typeAliases 别名
    10       typeAliasesElement(root.evalNode("typeAliases"));
    11       //解析子节点plugins 插件
    12       pluginElement(root.evalNode("plugins"));
    13       //解析子节点objectFactory mybatis为结果创建对象时都会用到objectFactory
    14       objectFactoryElement(root.evalNode("objectFactory"));
    15       //解析子节点的封装对象
    16       objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
    17       reflectorFactoryElement(root.evalNode("reflectorFactory"));
    18       //解析settings标签的文件配置
    19       settingsElement(settings);
    20       //配置运行环境
    21       environmentsElement(root.evalNode("environments"));
    22       //解析子节点配置数据库供应商
    23       databaseIdProviderElement(root.evalNode("databaseIdProvider"));
    24       //解析对象类型处理器,处理Java的pojo类型与数据库类型的映射
    25       typeHandlerElement(root.evalNode("typeHandlers"));
    26       //解析子节点的mappers
    27       mapperElement(root.evalNode("mappers"));
    28     } catch (Exception e) {
    29       throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    30     }
    31   }
    environmentsElement(root.evalNode("environments"));主要处理连接数据库配置,在mybatis配置文件中的写法为:
     1 <!--默认为development 环境,通过此配置会寻找 id="development"配置-->
     2 <environments default="development">
     3        <!--当前运行环境-->
     4         <environment id="development">
     5           <!--指定任务管理器-->
     6             <transactionManager type="JDBC"/>
     7           <!--指定数据源-->
     8             <dataSource type="POOLED">
     9                 <property name="driver" value="${jdbc.driver}"/>
    10                 <property name="url" value="${jdbc.url}"/>
    11                 <property name="username" value="${jdbc.username}"/>
    12                 <property name="password" value="${jdbc.password}"/>
    13             </dataSource>
    14         </environment>
    15     </environments>
    任务管理器 <transactionManager type="JDBC"/>中type属性有两个值分别是 JDBC,MANAGED。type也可以自定义实现事务管理
    JDBC是指 JdbcTransactionFactory 生成的 JdbcTransaction 对象实现。它是以 JDBC 的方式对数据库的提交和回滚进行操作
    MANAGED 使用 ManagedTransactionFactory 生成的 ManagedTransaction 对象实现。它的提交和回滚方法不用任何操作,而是把事务交给容器处理。在默认情况下,它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
    数据源配置形式 <dataSource type="POOLED"> 中type的属性值分别为JNDI,POOLED,UNPOOLED
    UNPOOLED 采用非数据库池的管理方式,每次请求都会打开一个新的数据库连接,所以创建会比较慢。基于UnpooledDataSourceFactory实现
    POOLED数据源 POOLED 利用“池”的概念将 JDBC 的 Connection 对象组织起来,它开始会有一些空置,并且已经连接好的数据库连接,所以请求时,无须再建立和验证,省去了创建新的连接实例时所必需的初始化和认证时间。它还控制最大连接数,避免过多的连接导致系统瓶颈。是基于PooledDataSourceFactory实现
    JNDI数据源 JNDI 的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。是基于JndiDataSourceFactory实现
    environmentsElement方法为:
     1   private void environmentsElement(XNode context) throws Exception {
     2     if (context != null) {
     3       if (environment == null) {
     4         environment = context.getStringAttribute("default");
     5       }
     6       for (XNode child : context.getChildren()) {
     7       //获取environment配置ID值
     8         String id = child.getStringAttribute("id");
     9     //判断指定的环境ID与各子节点的环境ID是否一致
    10         if (isSpecifiedEnvironment(id)) {
    11       //加载事务管理器
    12           TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
    13       //加载数据源
    14           DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
    15           DataSource dataSource = dsFactory.getDataSource();
    16           Environment.Builder environmentBuilder = new Environment.Builder(id)
    17               .transactionFactory(txFactory)
    18               .dataSource(dataSource);
    19           configuration.setEnvironment(environmentBuilder.build());
    20         }
    21       }
    22     }
    23   }
    isSpecifiedEnvironment(id)方法为:
     1  private boolean isSpecifiedEnvironment(String id) {
     2     if (environment == null) {
     3       throw new BuilderException("No environment specified.");
     4     } else if (id == null) {
     5       throw new BuilderException("Environment requires an id attribute.");
     6     } else if (environment.equals(id)) {
     7       return true;
     8     }
     9     return false;
    10   }
    transactionManagerElement方法为
     1 private TransactionFactory transactionManagerElement(XNode context) throws Exception {
     2     if (context != null) {
     3       String type = context.getStringAttribute("type");
     4    //获取子节点
     5       Properties props = context.getChildrenAsProperties();
     6    //根据type参数获取事务管理器实例
     7       TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();
     8       factory.setProperties(props);
     9       return factory;
    10     }
    dataSourceElement数据源加载
     1 private DataSourceFactory dataSourceElement(XNode context) throws Exception {
     2     if (context != null) {
     3       String type = context.getStringAttribute("type");
     4       Properties props = context.getChildrenAsProperties();
     5       DataSourceFactory factory = (DataSourceFactory) resolveClass(type).newInstance();
     6       factory.setProperties(props);
     7       return factory;
     8     }
     9     throw new BuilderException("Environment declaration requires a DataSourceFactory.");
    10   }
     
     
     
    
    


    生于忧患,死于安乐
  • 相关阅读:
    英文论文降重
    A100和H100两款NVIDIA顶级双精度浮点数矢量运算芯片被限制对华出口——警醒
    一段建筑学上的历史——“赫鲁晓夫楼”
    再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(8) —— 2021年9月SOTA的TDL算法——《Optimistic Temporal Difference Learning for 2048》——完结篇
    说说中国高校理工科教育中的基础概念混乱问题——GPU是ASIC吗
    谈谈理工科生是否应该具备一定社会类学科的知识
    java程序在windows后台执行的办法
    Java maven 多模块实现
    Java maven 多模块实现 编译多架包 .jar
    插件报错:SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".解决方案
  • 原文地址:https://www.cnblogs.com/songlove/p/14602826.html
Copyright © 2020-2023  润新知