Mybatis的Environment解析詳解

今天來具體看一下如何解析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. }  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章