Mybatis的Environment解析详解

不羁岁月 提交于 2019-12-06 12:17:48

今天来具体看一下如何解析environments 
//XMLConfigBuilder 

Java代码

  1. private void parseConfiguration(XNode root)  
  2.     {  
  3.         try  
  4.         {  
  5.             propertiesElement(root.evalNode("properties"));  
  6.             typeAliasesElement(root.evalNode("typeAliases"));  
  7.             pluginElement(root.evalNode("plugins"));  
  8.             objectFactoryElement(root.evalNode("objectFactory"));  
  9.             objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));  
  10.             settingsElement(root.evalNode("settings"));  
  11.         //解析environments  
  12.             environmentsElement(root.evalNode("environments"));  
  13.             databaseIdProviderElement(root.evalNode("databaseIdProvider"));  
  14.             typeHandlerElement(root.evalNode("typeHandlers"));  
  15.             mapperElement(root.evalNode("mappers"));  
  16.         }  
  17.         catch(Exception e)  
  18.         {  
  19.             throw new BuilderException((new StringBuilder()).append("Error parsing SQL Mapper Configuration. Cause: ").append(e).toString(), e);  
  20.         }  
  21.     }  
  22. //解析environments  
  23. private void environmentsElement(XNode context)  
  24.         throws Exception  
  25.     {  
  26.         if(context != null)  
  27.         {  
  28.             if(C == null)  
  29.                 environment = context.getStringAttribute("default");  
  30.             Iterator i$ = context.getChildren().iterator();  
  31.         //遍历environments的child节点environment,并解析  
  32.             do  
  33.             {  
  34.                 if(!i$.hasNext())  
  35.                     break;  
  36.                 XNode child = (XNode)i$.next();  
  37.                 String id = child.getStringAttribute("id");  
  38.         //如果environment的id属性,与environments的default相同时,才解析  
  39.                 if(isSpecifiedEnvironment(id))  
  40.                 {  
  41.             //解析transactionManager  
  42.                     TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));  
  43.                     //解析dataSource  
  44.             DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));  
  45.                     javax.sql.DataSource dataSource = dsFactory.getDataSource();  
  46.                     org.apache.ibatis.mapping.Environment.Builder environmentBuilder = (new org.apache.ibatis.mapping.Environment.Builder(id)).transactionFactory(txFactory).dataSource(dataSource);  
  47.                     configuration.setEnvironment(environmentBuilder.build());  
  48.                 }  
  49.             } while(true);  
  50.         }  
  51.     }  


//解析transactionManager 
先看configuration的构造,启动有JDBC,POOLED类型的映射关系,这个在解析environment节点时,需要用到  下载

Java代码

  1. typeAliasRegistry.registerAlias("JDBC", org/apache/ibatis/transaction/jdbc/JdbcTransactionFactory);  
  2. typeAliasRegistry.registerAlias("POOLED", org/apache/ibatis/datasource/pooled/PooledDataSourceFactory);  


 

Java代码

  1. public Configuration()  
  2.     {  
  3.         safeRowBoundsEnabled = false;  
  4.         safeResultHandlerEnabled = true;  
  5.         mapUnderscoreToCamelCase = false;  
  6.         aggressiveLazyLoading = true;  
  7.         multipleResultSetsEnabled = true;  
  8.         useGeneratedKeys = false;//允许JDBC支持生成的键  
  9.         useColumnLabel = true;  
  10.         cacheEnabled = true;//全局的映射器启用或禁用缓存  
  11.         callSettersOnNulls = false;  
  12.         localCacheScope = LocalCacheScope.SESSION;//本地一级缓存作用域  
  13.         jdbcTypeForNull = JdbcType.OTHER;  
  14.         lazyLoadTriggerMethods = new HashSet(Arrays.asList(new String[] {  
  15.             "equals""clone""hashCode""toString"  
  16.         }));  
  17.         defaultExecutorType = ExecutorType.SIMPLE;  
  18.         autoMappingBehavior = AutoMappingBehavior.PARTIAL;  
  19.         variables = new Properties();  
  20.         objectFactory = new DefaultObjectFactory();//默认ObjectFactory  
  21.         objectWrapperFactory = new DefaultObjectWrapperFactory();//默认DefaultObjectWrapperFactory  
  22.         mapperRegistry = new MapperRegistry(this);  
  23.         lazyLoadingEnabled = false;  
  24.         interceptorChain = new InterceptorChain();//插件链  
  25.         typeHandlerRegistry = new TypeHandlerRegistry();//类型处理注册器  
  26.         typeAliasRegistry = new TypeAliasRegistry();//类型别名注册器  
  27.         languageRegistry = new LanguageDriverRegistry();  
  28.     //mappedStatements Map  
  29.         mappedStatements = new StrictMap("Mapped Statements collection");  
  30.     //mappedStatements,method,二级缓存  
  31.         caches = new StrictMap("Caches collection");  
  32.     //MapperInterface 方法返回结果类型Map  
  33.         resultMaps = new StrictMap("Result Maps collection");  
  34.         //MapperInterface 方法参数类型Map  
  35.         parameterMaps = new StrictMap("Parameter Maps collection");  
  36.     //主键生成器Map  
  37.         keyGenerators = new StrictMap("Key Generators collection");  
  38.         loadedResources = new HashSet();  
  39.     //Mapper.xml 中statement片段  
  40.         sqlFragments = new StrictMap("XML fragments parsed from previous mappers");  
  41.     //未解析处理的statements  
  42.         incompleteStatements = new LinkedList();  
  43.     //未解析处理的CacheRefs  
  44.         incompleteCacheRefs = new LinkedList();  
  45.     //未解析处理的ResultMaps  
  46.         incompleteResultMaps = new LinkedList();  
  47.     //未解析处理的Methods  
  48.         incompleteMethods = new LinkedList();  
  49.         cacheRefMap = new HashMap();  
  50.         typeAliasRegistry.registerAlias("JDBC", org/apache/ibatis/transaction/jdbc/JdbcTransactionFactory);  
  51.         typeAliasRegistry.registerAlias("MANAGED", org/apache/ibatis/transaction/managed/ManagedTransactionFactory);  
  52.         typeAliasRegistry.registerAlias("JNDI", org/apache/ibatis/datasource/jndi/JndiDataSourceFactory);  
  53.         typeAliasRegistry.registerAlias("POOLED", org/apache/ibatis/datasource/pooled/PooledDataSourceFactory);  
  54.         typeAliasRegistry.registerAlias("UNPOOLED", org/apache/ibatis/datasource/unpooled/UnpooledDataSourceFactory);  
  55.         typeAliasRegistry.registerAlias("PERPETUAL", org/apache/ibatis/cache/impl/PerpetualCache);  
  56.         typeAliasRegistry.registerAlias("FIFO", org/apache/ibatis/cache/decorators/FifoCache);  
  57.         typeAliasRegistry.registerAlias("LRU", org/apache/ibatis/cache/decorators/LruCache);  
  58.         typeAliasRegistry.registerAlias("SOFT", org/apache/ibatis/cache/decorators/SoftCache);  
  59.         typeAliasRegistry.registerAlias("WEAK", org/apache/ibatis/cache/decorators/WeakCache);  
  60.         typeAliasRegistry.registerAlias("VENDOR", org/apache/ibatis/mapping/VendorDatabaseIdProvider);  
  61.         typeAliasRegistry.registerAlias("XML", org/apache/ibatis/scripting/xmltags/XMLLanguageDriver);  
  62.         typeAliasRegistry.registerAlias("RAW", org/apache/ibatis/scripting/defaults/RawLanguageDriver);  
  63.         typeAliasRegistry.registerAlias("SLF4J", org/apache/ibatis/logging/slf4j/Slf4jImpl);  
  64.         typeAliasRegistry.registerAlias("COMMONS_LOGGING", org/apache/ibatis/logging/commons/JakartaCommonsLoggingImpl);  
  65.         typeAliasRegistry.registerAlias("LOG4J", org/apache/ibatis/logging/log4j/Log4jImpl);  
  66.         typeAliasRegistry.registerAlias("JDK_LOGGING", org/apache/ibatis/logging/jdk14/Jdk14LoggingImpl);  
  67.         typeAliasRegistry.registerAlias("STDOUT_LOGGING", org/apache/ibatis/logging/stdout/StdOutImpl);  
  68.         typeAliasRegistry.registerAlias("NO_LOGGING", org/apache/ibatis/logging/nologging/NoLoggingImpl);  
  69.         typeAliasRegistry.registerAlias("CGLIB", org/apache/ibatis/executor/loader/CglibProxyFactory);  
  70.         typeAliasRegistry.registerAlias("JAVASSIST", org/apache/ibatis/executor/loader/JavassistProxyFactory);  
  71.         languageRegistry.setDefaultDriverClass(org/apache/ibatis/scripting/xmltags/XMLLanguageDriver);  
  72.         languageRegistry.register(org/apache/ibatis/scripting/defaults/RawLanguageDriver);  
  73.     }  


从上可以看出JDBC,POOLED类型别名的映射关系如下: 
JDBC,JdbcTransactionFactory  下载
POOLED,PooledDataSourceFactory 
 

Java代码

  1. <environments default="development">  
  2.         <environment id="development">  
  3.             <transactionManager type="JDBC" />  
  4.             <dataSource type="POOLED">  
  5.                 <property name="driver" value="${driver}" />  
  6.                 <property name="url" value="${url}" />  
  7.                 <property name="username" value="${username}" />  
  8.                 <property name="password" value="${password}" />  
  9.             </dataSource>  
  10.         </environment>  
  11. </environments>  


 

Java代码

 

  1. private TransactionFactory transactionManagerElement(XNode context)  
  2.         throws Exception  
  3.     {  
  4.         if(context != null)  
  5.         {  
  6.             String type = context.getStringAttribute("type");  
  7.             Properties props = context.getChildrenAsProperties();  
  8.         //从类型解决器中,获取type对应的类型的实例,从上面的配置来看  
  9.         //实际为JdbcTransactionFactory  
  10.             TransactionFactory factory = (TransactionFactory)resolveClass(type).newInstance();  
  11.         //设置JdbcTransactionFactory属性  
  12.             factory.setProperties(props);  
  13.             return factory;  
  14.         } else  
  15.         {  
  16.             throw new BuilderException("Environment declaration requires a TransactionFactory.");  
  17.         }  
  18.     }  



//JdbcTransactionFactory 

Java代码

下载

  1. public class JdbcTransactionFactory  
  2.     implements TransactionFactory  
  3. {  
  4.     public void setProperties(Properties properties)  
  5.     {  
  6.     }  
  7.    //根据数据连接新建事务  
  8.     public Transaction newTransaction(Connection conn)  
  9.     {  
  10.         return new JdbcTransaction(conn);  
  11.     }  
  12.     //根据数据源和事务级别和是否自动提交,新建事务  
  13.     public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit)  
  14.     {  
  15.         return new JdbcTransaction(ds, level, autoCommit);  
  16.     }  
  17. }  



//TransactionFactory 

Java代码

 

  1. public interface TransactionFactory  
  2. {  
  3.     public abstract void setProperties(Properties properties);  
  4.     public abstract Transaction newTransaction(Connection connection);  
  5.     public abstract Transaction newTransaction(DataSource datasource, TransactionIsolationLevel transactionisolationlevel, boolean flag);  
  6. }  


现在来看一下jdbc事务 
 

Java代码

下载

  1. public class JdbcTransaction  
  2.     implements Transaction  
  3. {  
  4.     private static final Log log = LogFactory.getLog(org/apache/ibatis/transaction/jdbc/JdbcTransaction);  
  5.     protected Connection connection;//数据库连接  
  6.     protected DataSource dataSource;//数据源  
  7.     protected TransactionIsolationLevel level;//事务级别  
  8.     protected boolean autoCommmit;//自动提交属性  
  9.   
  10.     public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit)  
  11.     {  
  12.         dataSource = ds;  
  13.         level = desiredLevel;  
  14.         autoCommmit = desiredAutoCommit;  
  15.     }  
  16.   
  17.     public JdbcTransaction(Connection connection)  
  18.     {  
  19.         this.connection = connection;  
  20.     }  
  21.   
  22.     public Connection getConnection()  
  23.         throws SQLException  
  24.     {  
  25.         if(connection == null)  
  26.             openConnection();  
  27.         return connection;  
  28.     }  
  29.   
  30.     public void commit()  
  31.         throws SQLException  
  32.     {  
  33.         if(connection != null && !connection.getAutoCommit())  
  34.         {  
  35.             if(log.isDebugEnabled())  
  36.                 log.debug((new StringBuilder()).append("Committing JDBC Connection [").append(connection).append("]").toString());  
  37.             connection.commit();  
  38.         }  
  39.     }  
  40.   
  41.     public void rollback()  
  42.         throws SQLException  
  43.     {  
  44.         if(connection != null && !connection.getAutoCommit())  
  45.         {  
  46.             if(log.isDebugEnabled())  
  47.                 log.debug((new StringBuilder()).append("Rolling back JDBC Connection [").append(connection).append("]").toString());  
  48.             connection.rollback();  
  49.         }  
  50.     }  
  51.   
  52.     public void close()  
  53.         throws SQLException  
  54.     {  
  55.         if(connection != null)  
  56.         {  
  57.             resetAutoCommit();  
  58.             if(log.isDebugEnabled())  
  59.                 log.debug((new StringBuilder()).append("Closing JDBC Connection [").append(connection).append("]").toString());  
  60.             connection.close();  
  61.         }  
  62.     }  
  63.   
  64.     protected void setDesiredAutoCommit(boolean desiredAutoCommit)  
  65.     {  
  66.         try  
  67.         {  
  68.             if(connection.getAutoCommit() != desiredAutoCommit)  
  69.             {  
  70.                 if(log.isDebugEnabled())  
  71.                     log.debug((new StringBuilder()).append("Setting autocommit to ").append(desiredAutoCommit).append(" on JDBC Connection [").append(connection).append("]").toString());  
  72.                 connection.setAutoCommit(desiredAutoCommit);  
  73.             }  
  74.         }  
  75.         catch(SQLException e)  
  76.         {  
  77.             throw new TransactionException((new StringBuilder()).append("Error configuring AutoCommit.  Your driver may not support getAutoCommit() or setAutoCommit(). Requested setting: ").append(desiredAutoCommit).append(".  Cause: ").append(e).toString(), e);  
  78.         }  
  79.     }  
  80.   
  81.     protected void resetAutoCommit()  
  82.     {  
  83.         try  
  84.         {  
  85.             if(!connection.getAutoCommit())  
  86.             {  
  87.                 if(log.isDebugEnabled())  
  88.                     log.debug((new StringBuilder()).append("Resetting autocommit to true on JDBC Connection [").append(connection).append("]").toString());  
  89.                 connection.setAutoCommit(true);  
  90.             }  
  91.         }  
  92.         catch(SQLException e)  
  93.         {  
  94.             log.debug((new StringBuilder()).append("Error resetting autocommit to true before closing the connection.  Cause: ").append(e).toString());  
  95.         }  
  96.     }  
  97.     //获取connection  
  98.     protected void openConnection()  
  99.         throws SQLException  
  100.     {  
  101.         if(log.isDebugEnabled())  
  102.             log.debug("Openning JDBC Connection");  
  103.         connection = dataSource.getConnection();  
  104.         if(level != null)  
  105.             connection.setTransactionIsolation(level.getLevel());  
  106.         setDesiredAutoCommit(autoCommmit);  
  107.     }  
  108. }  


//Transaction 

Java代码

 

  1. public interface Transaction  
  2. {  
  3.   
  4.     public abstract Connection getConnection()  
  5.         throws SQLException;  
  6.   
  7.     public abstract void commit()  
  8.         throws SQLException;  
  9.   
  10.     public abstract void rollback()  
  11.         throws SQLException;  
  12.   
  13.     public abstract void close()  
  14.         throws SQLException;  
  15. }  


从上面可以看出jdbc对应的事务工厂为JdbcTransactionFactory,由JdbcTransactionFactory,根据数据源,事务级别以及自动提交属性来,创建JdbcTransaction,而JdbcTransaction的事务管理,是通过数据连接connection,而connection是从datasource获取,JdbcTransaction的事务管理,就是依靠相应的数据库driver,来管理,实际依赖于数据库。  下载

//解析dataSource 

Java代码

 

  1. private DataSourceFactory dataSourceElement(XNode context)  
  2.         throws Exception  
  3.     {  
  4.         if(context != null)  
  5.         {  
  6.         //获取数据源的类型,和属性  
  7.             String type = context.getStringAttribute("type");  
  8.             Properties props = context.getChildrenAsProperties();  
  9.         //根据type从configuration的类型处理器,获取具体的DataSourceFactory  
  10.         //从上文,我们看一看到type为POOLED,对应的是PooledDataSourceFactory  
  11.             DataSourceFactory factory = (DataSourceFactory)resolveClass(type).newInstance();  
  12.             factory.setProperties(props);  
  13.             return factory;  
  14.         } else  
  15.         {  
  16.             throw new BuilderException("Environment declaration requires a DataSourceFactory.");  
  17.         }  
  18.     }  


// PooledDataSourceFactory 

Java代码

 

  1. public class PooledDataSourceFactory extends UnpooledDataSourceFactory  
  2. {  
  3.   
  4.     public PooledDataSourceFactory()  
  5.     {  
  6.         dataSource = new PooledDataSource();  
  7.     }  
  8. }  

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!