mybatis 學習之多數據源整合

繼續上篇文章如何使用mybatis3+spring3而且配置多數據源呢 

先上代碼在講解吧 
替換上一篇中spring中datasource的配置 
Java代碼   收藏代碼
  1. <!-- 數據源配置 -->  
  2. <bean id="ds1" class="org.apache.commons.dbcp.BasicDataSource"  
  3.     destroy-method="close">  
  4.     <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
  5.     <property name="url"  
  6.         value="jdbc:mysql://localhost:3306/payoffdatabase?useUnicode=true&amp;characterEncoding=UTF-8" />  
  7.     <property name="username" value="root" />  
  8.     <property name="password" value="root" />  
  9.     <property name="defaultAutoCommit" value="true"></property>  
  10. </bean>  
  11.   
  12. <bean id="ds2" class="org.apache.commons.dbcp.BasicDataSource"  
  13.     destroy-method="close">  
  14.     <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
  15.     <property name="url"  
  16.         value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8" />  
  17.     <property name="username" value="root" />  
  18.     <property name="password" value="root" />  
  19.     <property name="defaultAutoCommit" value="true"></property>  
  20. </bean>  
  21.   
  22.   
  23.  <bean id="dataSource" class="a.b.router.DynamicDataSource">  
  24.     <property name="targetDataSources">  
  25.         <map key-type="java.lang.String">  
  26.             <entry value-ref="ds1" key="ds1"></entry>  
  27.             <entry value-ref="ds2" key="ds2"></entry>  
  28.         </map>  
  29.     </property>  
  30.     <property name="defaultTargetDataSource" ref="ds1"></property>  
  31. </bean>  


新的類DynamicDataSource 
Java代碼   收藏代碼
  1. package a.b.router;  
  2.   
  3. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;  
  4.   
  5. public class DynamicDataSource extends AbstractRoutingDataSource {  
  6.     @Override  
  7.     protected Object determineCurrentLookupKey() {  
  8.         return DataSourceContextHolder.getDbType();  
  9.     }  
  10. }  

新的類DataSourceContextHolder 
Java代碼   收藏代碼
  1. package a.b.router;  
  2.   
  3. public class DataSourceContextHolder {  
  4.   
  5.     private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
  6.   
  7.     public static void setDbType(String dbType) {  
  8.         contextHolder.set(dbType);  
  9.     }  
  10.   
  11.     public static String getDbType() {  
  12.         return ((String) contextHolder.get());  
  13.     }  
  14.   
  15.     public static void clearDbType() {  
  16.         contextHolder.remove();  
  17.     }  
  18. }  


原來的單元測試新添加一行信息,修改成 
Java代碼   收藏代碼
  1. @Test  
  2. public void addTest() throws Exception {  
  3.     UserLogin userLogin = new UserLogin();  
  4.     userLogin.setPassword("102");  
  5.     userLogin.setUsername("102");  
  6.     DataSourceContextHolder.setDbType("ds2");  
  7.   
  8.     service.add(userLogin);  
  9. }  


最主要的變化是DynamicDataSource 類,這個類繼承了AbstractRoutingDataSource,咱們再繼續考察,發現這個類實現了datasource這個接口。 

再仔細研究,發現我配置了多個數據源給DynamicDataSource,默認的數據源是ds1。 
咱們研究下AbstractRoutingDataSource類的代碼,主要是兩個實現datasource的方法 
Java代碼   收藏代碼
  1. public Connection getConnection() throws SQLException {  
  2.     return determineTargetDataSource().getConnection();  
  3. }  
  4.   
  5. public Connection getConnection(String username, String password) throws SQLException {  
  6.     return determineTargetDataSource().getConnection(username, password);  
  7. }  

根據這段代碼發現主要玄機都在determineTargetDataSource()方法上。 

Java代碼   收藏代碼
  1. protected DataSource determineTargetDataSource() {  
  2.         Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");  
  3.         Object lookupKey = determineCurrentLookupKey();  
  4.         DataSource dataSource = this.resolvedDataSources.get(lookupKey);  
  5.         if (dataSource == null && (this.lenientFallback || lookupKey == null)) {  
  6.             dataSource = this.resolvedDefaultDataSource;  
  7.         }  
  8.         if (dataSource == null) {  
  9.             throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");  
  10.         }  
  11.         return dataSource;  
  12.     }  

根據這段代碼發現,首先在使用數據源以前,首先判斷使用數據源的key,也就是咱們配置給 
Java代碼   收藏代碼
  1. private Map<Object, Object> targetDataSources;  
這個map中的key值,找到key值以後再找到對應的datasource而後並使用這個數據源。  從上面咱們發現,實際上DynamicDataSource只是在內部封裝了數據源,而後調用它,只不過在內部他加了一些控制而已。(此處不知道是否能夠理解爲代理模式)  再深一步想一想,此處使用的orm層是mybatis,若是換成hibernate呢,或者jdbctemplate呢。  實際上這個方法都適用。
相關文章
相關標籤/搜索